text:
module Layer2Tests

using Test
using HDF5
using RandomMatrices
using LinearAlgebra

using PicoQuant

include("test_utils.jl")

@testset "Layer 2 tests" begin
    """
        function dsl_backend_teardown()

    Function to cleanup after the dslbackend
    """
    function dsl_backend_teardown()
        rm("contract_network.tl", force=true)
        rm("tensor_data.h5", force=true)
    end

    """Dictionary of init and finalise methods for testing backends"""
    backends = Dict("DSLBackend" =>
                    Dict(:init => () -> DSLBackend("contract_network.tl", "tensor_data.h5", "", true),
                        # :execute => (args...) -> execute_dsl_file(ComplexF64, args...),
                        :execute => execute_dsl_file,
                        :finalise => dsl_backend_teardown),

                    "InteractiveBackend" =>
                    Dict(:init => InteractiveBackend,
                        :execute => () -> (),
                        :finalise => () -> ())
                    )

    for (backend_name, backend_funcs) in pairs(backends)

        @testset "Test contract functions for $backend_name" begin

            # Create a tensor network and contraction plan to work with.
            qasm_str = """OPENQASM 2.0;
                        include "qelib1.inc";
                        qreg q[3];
                        h q[0];
                        cx q[0],q[1];
                        cx q[1],q[2];"""

            try
                circ = load_qasm_as_circuit(qasm_str)
                tng = convert_qiskit_circ_to_network(circ, backend_funcs[:init]())
                add_input!(tng, "000")
                add_output!(tng, "000")
                plan = random_contraction_plan(tng)

                # Test if contract_network creates files with dsl and tensor data.
                contract_network!(tng, plan)

                backend_funcs[:execute]()

                # Is there only one node left after the contraction?
                @test begin
                    length(tng.nodes) == 1
                end
            finally
                backend_funcs[:finalise]()
            end

            try
                # Create a network which will be disjoint when all edges are contracted
                qasm_str = """OPENQASM 2.0;
                            include "qelib1.inc";
                            qreg q[2];
                            h q[0];
                            h q[1];"""

                circ = load_qasm_as_circuit(qasm_str)
                tng = convert_qiskit_circ_to_network(circ, backend_funcs[:init]())
                add_input!(tng, "00")
                plan = random_contraction_plan(tng)

                contract_network!(tng, plan, "vector")

                # Is there only one node left in nodes array after the contraction?
                @test begin
                    length(tng.nodes) == 1
                end

                backend_funcs[:execute]()

                # Check if the final tensor is a vector
                @test begin
                    result = load_tensor_data(tng, :result)
                    length(size(result)) == 1
                end

                @test begin
                    result = load_tensor_data(tng, :result)
                    real(result)[1] ≈ 1/2
                end
            finally
                backend_funcs[:finalise]()
            end
        end

        @testset "Test full wavefunction contraction for $backend_name" begin

            # Create a tensor network to work with.
            qasm_str = """OPENQASM 2.0;
                        include "qelib1.inc";
                        qreg q[3];
                        h q[0];
                        cx q[0],q[1];
                        cx q[0],q[1];
                        cx q[0],q[2];
                        """

            try
                circ = load_qasm_as_circuit(qasm_str)
                tn = convert_qiskit_circ_to_network(circ, backend_funcs[:init]())
                add_input!(tn, "000")

                # See if full wavefunction contraction completes.
                full_wavefunction_contraction!(tn, "vector")

                # check if the computed metrics are correct
                @test begin
                    max_size = tn.backend.metrics.max_tensor_size == 8
                    total_space = tn.backend.metrics.total_space_allocated == 44
                    flops = tn.backend.metrics.flops == 124
                    max_size && total_space && flops
                end

                backend_funcs[:execute]()

                # Is there only one node left after the contraction?
                @test begin
                    length(tn.nodes) == 1
                end
            finally
                backend_funcs[:finalise]()
            end
        end

        @testset "Test netcon contraction function for $backend_name" begin
            # Create a tensor network to work with.
            qasm_str = """OPENQASM 2.0;
                        include "qelib1.inc";
                        qreg q[3];
                        h q[0];
                        cx q[0],q[1];
                        cx q[0],q[2];
                        """

            try
                circ = load_qasm_as_circuit(qasm_str)
                tn = convert_qiskit_circ_to_network(circ, backend_funcs[:init]())
                add_input!(tn, "000")
                add_output!(tn, "000")

                # See if full wavefunction contraction completes.
                netcon_contraction!(tn)

                backend_funcs[:execute]()

                # Is there only one node left after the contraction?
                @test begin
                    length(tn.nodes) == 1
                end
            finally
                backend_funcs[:finalise]()
            end
        end

        @testset "Test bgreedy contraction function for $backend_name" begin
            # Create a tensor network to work with.
            qasm_str = """OPENQASM 2.0;
                        include "qelib1.inc";
                        qreg q[3];
                        h q[0];
                        cx q[0],q[1];
                        cx q[0],q[2];
                        """

            try
                circ = load_qasm_as_circuit(qasm_str)
                tn = convert_qiskit_circ_to_network(circ, backend_funcs[:init]())
                add_input!(tn, "000")
                add_output!(tn, "000")

                # See if full wavefunction contraction completes.
                bgreedy_contraction!(tn)

                backend_funcs[:execute]()

                # Is there only one node left after the contraction?
                @test begin
                    length(tn.nodes) == 1
                end
            finally
                backend_funcs[:finalise]()
            end
        end

        @testset "Test full wavefunction and MPS contractions match for $backend_name" begin

            try
                circ = create_simple_preparation_circuit(3, 1).compose(create_ghz_preparation_circuit(3))

                # simulate with full wf approach
                tn = convert_qiskit_circ_to_network(circ, backend_funcs[:init](), decompose=true, transpile=true)
                add_input!(tn, "0"^tn.number_qubits)

                # See if full wavefunction contraction completes.
                full_wavefunction_contraction!(tn, "vector")

                backend_funcs[:execute]()

                full_wf = load_tensor_data(tn, :result)

                tn = convert_qiskit_circ_to_network(circ, backend_funcs[:init](), decompose=true, transpile=true)
                add_input!(tn, "0"^tn.number_qubits)

                # See if full wavefunction contraction completes.
                mps_nodes = contract_mps_tensor_network_circuit!(tn)
                calculate_mps_amplitudes!(tn, mps_nodes)

                backend_funcs[:execute]()

                mps_wf = load_tensor_data(tn, :result)

                # Is there only one node left after the contraction?
                @test begin
                    mps_wf ≈ full_wf
                end
            finally
                backend_funcs[:finalise]()
            end
        end

        @testset "Test tensor chain compression for $backend_name" begin

            @test begin
                try
                    tn = TensorNetworkCircuit(2, backend_funcs[:init]())
                    add_input!(tn, "00")
                    compress_tensor_chain!(tn, collect(keys(tn.nodes)))
                    length(tn.nodes) == 2
                finally
                    backend_funcs[:finalise]()
                end
            end

            @testset begin

                try
                    # create a network and apply a ghz state preparation
                    # circuit. Then apply two additional cnot gates which should
                    # cancel out. At this point there should be 3 virtual bonds
                    # each with dimension 2. After a compression operation, this
                    # will be reduced to a single bond with dimension 2
                    qasm_str = """OPENQASM 2.0;
                                include "qelib1.inc";
                                qreg q[2];
                                h q[0];
                                cx q[0],q[1];
                                cx q[0],q[1];
                                cx q[0],q[1];
                                """
                    circ = load_qasm_as_circuit(qasm_str)
                    tn = convert_qiskit_circ_to_network(circ, backend_funcs[:init]())
                    add_input!(tn, "0"^2)
                    decompose_tensor!(tn, :node_2, [:index_3, :index_4],
                                    [:index_2, :index_5])
                    decompose_tensor!(tn, :node_3, [:index_4, :index_6],
                                    [:index_5, :index_7])
                    decompose_tensor!(tn, :node_4, [:index_6, :index_8],
                                    [:index_7, :index_9])

                    # contract all links except the virtual and open edges
                    plan = [k for (k, v) in pairs(tn.edges) if !v.virtual &&
                                                            v.src !== nothing &&
                                                            v.dst !== nothing]

                    for edge in plan
                        contract_pair!(tn, edge)
                    end

                    compress_tensor_chain!(tn, [:node_18, :node_19])

                    idx = findfirst(x -> x == :index_14, tn.nodes[:node_18].indices)

                    if backend_name == "DSLBackend"
                        save_output(tn, :node_18, "node_18")
                    end

                    backend_funcs[:execute]()

                    result = load_tensor_data(tn, :node_18)

                    size(result)[idx] == 2
                finally
                    backend_funcs[:finalise]()
                end
            end
        end

        @testset "Test tensor network contraction with MPS, full vector for $backend_name" begin
            @test begin
                try
                    n = 5
                    circ = create_ghz_preparation_circuit(n)
                    tn = convert_qiskit_circ_to_network(circ,
                                                        backend_funcs[:init](),
                                                        decompose=true,
                                                        transpile=true)
                    add_input!(tn, "0"^n)
                    mps_nodes = contract_mps_tensor_network_circuit!(tn)
                    calculate_mps_amplitudes!(tn, mps_nodes)
                    backend_funcs[:execute]()
                    ref_output = zeros(ComplexF64, 2^n)
                    ref_output[[1, end]] .= 1/sqrt(2)
                    load_tensor_data(tn, :result) ≈ ref_output
                finally
                    backend_funcs[:finalise]()
                end
            end
        end

        @testset "Test tensor network contraction with MPS, select amplitudes for $backend_name" begin
            @test begin
                try
                    n = 5
                    circ = create_ghz_preparation_circuit(n)
                    tn = convert_qiskit_circ_to_network(circ,
                                                        backend_funcs[:init](),
                                                        decompose=true,
                                                        transpile=true)
                    add_input!(tn, "0"^n)
                    mps_nodes = contract_mps_tensor_network_circuit!(tn)
                    backend_funcs[:execute]()
                    mps_state = MPSState(tn, mps_nodes)
                    size(mps_state) == Tuple(ones(4) .* 2)
                    length(mps_state) == 2 << n
                    mps_state["11111"] ≈ mps_state["00000"] ≈ 1/sqrt(2)
                    mps_state["10101"] ≈ 0
                finally
                    backend_funcs[:finalise]()
                end
            end
        end

        @testset "Test decopmose with threshold option for backend $backend_name" begin
            @test begin
                try
                    # create distribution to sample from to get a random unitary matrix
                    dist = Haar(1)
                    d = 2
                    random_gate_data = reshape(rand(dist, d^2), (d, d, d, d))

                    tn = TensorNetworkCircuit(2, backend_funcs[:init]())
                    add_gate!(tn, random_gate_data, [1, 2])

                    threshold = 0.5
                    # decompose gate between qubits with threshold of 0.5
                    new_nodes = decompose_tensor!(tn,
                                                :node_1,
                                                [:index_1, :index_3],
                                                [:index_2, :index_4],
                                                threshold=threshold)
                    save_output(tn, new_nodes[1], String(new_nodes[1]))

                    backend_funcs[:execute]()

                    # decompose gate data manually and check threshold was applied
                    F = svd(reshape(permutedims(random_gate_data, (1, 3, 2, 4)), (d^2, d^2)))

                    S_norm = sqrt(sum(F.S .^ 2))
                    expected_dim = sum(F.S ./ S_norm .> threshold)
                    virtual_bonds = virtualedges(tn, new_nodes[1])
                    bond_idx = findfirst(x -> x == virtual_bonds[1], tn.nodes[new_nodes[1]].indices)
                    size(load_tensor_data(tn, new_nodes[1]))[bond_idx] == expected_dim
                finally
                    backend_funcs[:finalise]()
                end
            end

            @testset "Test decopmose with max_rank option for backend $backend_name" begin
                @test begin
                    try
                        # create distribution to sample from to get a random unitary matrix
                        dist = Haar(1)
                        d = 2
                        random_gate_data = reshape(rand(dist, d^2), (d, d, d, d))

                        tn = TensorNetworkCircuit(2, backend_funcs[:init]())
                        add_gate!(tn, random_gate_data, [1, 2])

                        max_rank = 1
                        # decompose gate between qubits with threshold of 1.0
                        new_nodes = decompose_tensor!(tn,
                                                    :node_1,
                                                    [:index_1, :index_3],
                                                    [:index_2, :index_4],
                                                    max_rank=max_rank)
                        save_output(tn, new_nodes[1], String(new_nodes[1]))

                        backend_funcs[:execute]()

                        virtual_bonds = virtualedges(tn, new_nodes[1])
                        bond_idx = findfirst(x -> x == virtual_bonds[1], tn.nodes[new_nodes[1]].indices)
                        size(load_tensor_data(tn, new_nodes[1]))[bond_idx] == max_rank
                    finally
                        backend_funcs[:finalise]()
                    end
                end
            end

            @testset "Test tensor slicing backend $backend_name" begin
                @test begin
                    try
                        n = 4
                        circ = create_simple_preparation_circuit(n, 2).compose(create_qft_circuit(n))

                        # contract the regular way
                        tn = convert_qiskit_circ_to_network(circ,
                                                            backend_funcs[:init](),
                                                            decompose=true,
                                                            transpile=true)
                        add_input!(tn, "0"^n)
                        full_wavefunction_contraction!(tn, "vector")
                        backend_funcs[:execute]()
                        wf = load_tensor_data(tn, :result)

                        # now decompose to 4 partitions and contract each partition separately
                        N = 4
                        wfs = []
                        for p in 1:N
                            tn = convert_qiskit_circ_to_network(circ,
                                                                backend_funcs[:init](),
                                                                decompose=true,
                                                                transpile=true)
                            add_input!(tn, "0"^n)
                            bond_labels, bond_values = partition_network_on_virtual_bonds(tn, N, p)
                            slice_tensor_network(tn, bond_labels, bond_values)
                            full_wavefunction_contraction!(tn, "vector")
                            backend_funcs[:execute]()
                            push!(wfs, load_tensor_data(tn, :result))
                        end
                        sum(wfs) ≈ wf
                    finally
                        backend_funcs[:finalise]()
                    end
                end
            end
        end
    end
end
end


text:
using Pkg.Artifacts, Pkg.BinaryPlatforms, Logging

export AnyPlatform, ExtendedPlatform, base_platform

"""
    AnyPlatform()

A special platform to be used to build platform-independent tarballs, like those
containing only header files.  [`FileProduct`](@ref) is the only product type
allowed with this platform.
"""
struct AnyPlatform <: Platform end
abi_agnostic(p::AnyPlatform) = p
Pkg.BinaryPlatforms.platform_name(::AnyPlatform) = "AnyPlatform"
Pkg.BinaryPlatforms.triplet(::AnyPlatform) = "any"
# Fallback on x86_64-linux-musl, but this shouldn't really matter in practice.
Pkg.BinaryPlatforms.arch(::AnyPlatform) = arch(Linux(:x86_64, libc=:musl))
Base.show(io::IO, ::AnyPlatform) = print(io, "AnyPlatform()")

## The extended platforms, to represent platforms beyond the standard ones in
## Pkg.BinaryPlatforms.

const ARCHITECTURE_FLAGS = begin
    # Better be always explicit about `-march` & `-mtune`:
    # https://lemire.me/blog/2018/07/25/it-is-more-complicated-than-i-thought-mtune-march-in-gcc/
    march_flags(arch) = ["-m$(f)=$(arch)" for f in ("arch", "tune")]
    Dict(
        :x86_64 => Dict(
            "x86_64" => march_flags("x86-64"),
            "avx" => march_flags("sandybridge"),
            "avx2" => march_flags("haswell"),
            "avx512" => march_flags("skylake-avx512"),
        ),
        :armv7l => Dict(
            "armv7l" => ["-march=armv7-a", "-mtune=generic-armv7-a"],
            "neon" => ["-march=armv7-a+neon", "-mtune=generic-armv7-a"],
            "vfp4" => ["-march=armv7-a+neon-vfpv4", "-mtune=generic-armv7-a"],
        ),
        :aarch64 => Dict(
            "armv8" => ["-march=armv8-a", "-mtune=cortex-a57"],
            "thunderx2" => ["-march=armv8.1-a", "-mtune=thunderx2t99"],
            "carmel" => ["-march=armv8.2-a+crypto+fp16+sha2+aes", "-mtune=cortex-a75"],
        ),
    )
end

"""
    ExtendedPlatform(p::Platform; kwargs...)

Extend a `Pkg.BinaryPlatforms.Platform` object with extra key-value mappings.
Arbitrary `String` values are supported, with the following constraints:

* the key cannot be any of "os", "arch", "libc", "libgfortran_version",
  "libstdcxx_version", "cxxstring_abi";
* if the key is called "march", only specific values are allowed, depending on
  what is the base platform,
* all strings should only use alphanumeric characters, the underscore, or the
  dot (the latter only for the value).

This type is, for example, used to tag a standard platform from
`Pkg.BinaryPlatforms` with additional features besides the C library or the
compiler ABI.

```jldoctest
julia> using BinaryBuilderBase

julia> ExtendedPlatform(Linux(:x86_64; libc=:glibc, compiler_abi=CompilerABI(; libgfortran_version=v"4")); march = "avx", cuda = "9.2")
ExtendedPlatform(Linux(:x86_64, libc=:glibc, compiler_abi=CompilerABI(libgfortran_version=v"4.0.0")); march="avx", cuda="9.2")
```
"""
struct ExtendedPlatform{P<:Platform} <: Platform
    p::P
    ext::Dict{String,String}
    function ExtendedPlatform{P}(p::P, ext::Dict{String,String}) where {P<:Platform}
        for (k, v) in ext
            if k in ("os", "arch", "libc", "libgfortran_version", "libstdcxx_version", "cxxstring_abi")
                # Throw an error if the key has a special meaning that would
                # make it ambiguous when running `Pkg.Artifacts.pack_platform!`.
                # This is the list of keys that are used there
                throw(ArgumentError("Invalid feature called \"$(k)\""))
            end
            # Validate special keys
            if k == "march" && (arch(p) ∉ keys(ARCHITECTURE_FLAGS) || v ∉ keys(ARCHITECTURE_FLAGS[arch(p)]))
                throw(ArgumentError("Key \"$(k)\" cannot have value \"$(v)\" for platform $(p)"))
            end
            # Make sure the key and the value don't have '+' in them
            if occursin('+', k) || occursin('+', v)
                throw(ArgumentError("The key and the value cannot contain the + sign"))
            end
        end
        return new(p, ext)
    end
end
ExtendedPlatform(p::P, ext::Dict{String,String}) where {P<:Platform} =
    ExtendedPlatform{P}(p, ext)
ExtendedPlatform(p::Platform; kwargs...) =
    ExtendedPlatform(p, Dict(string(k) => string(v) for (k, v) in pairs(kwargs)))
function ExtendedPlatform(p::ExtendedPlatform; kwargs...)
    for (k, v) in pairs(kwargs)
        key = String(k)
        if haskey(p.ext, key) && p.ext[key] != v
            error("The input platform has an incompatible feature $(key => p.ext[key])")
        end
    end
    ExtendedPlatform(p.p, merge(p.ext, Dict(string(k) => string(v) for (k, v) in pairs(kwargs))))
end

base_platform(p::Platform) = p
base_platform(ep::ExtendedPlatform) = ep.p
march(::Platform; default=nothing) = default
march(p::ExtendedPlatform; default = nothing) = get(p.ext, "march", default)

for f in (:isapple, :islinux, :iswindows, :isbsd)
    @eval Sys.$f(ep::ExtendedPlatform) = Sys.$f(base_platform(ep))
end

Pkg.BinaryPlatforms.platform_name(::ExtendedPlatform) = "ExtendedPlatform"
Pkg.BinaryPlatforms.arch(ep::ExtendedPlatform) = arch(base_platform(ep))
Pkg.BinaryPlatforms.libc(ep::ExtendedPlatform) = libc(base_platform(ep))
Pkg.BinaryPlatforms.call_abi(ep::ExtendedPlatform) = call_abi(base_platform(ep))
Pkg.BinaryPlatforms.compiler_abi(ep::ExtendedPlatform) = compiler_abi(base_platform(ep))
Pkg.BinaryPlatforms.triplet(ep::ExtendedPlatform) =
    triplet(base_platform(ep)) * join(["-$(k)+$(ep.ext[k])" for k in sort(collect(keys(ep.ext)))])
Pkg.BinaryPlatforms.platform_dlext(p::ExtendedPlatform) = platform_dlext(base_platform(p))

# Extending the same platform: match only if the base platforms match and the
# same keys in the dictionaries have the same values
Pkg.BinaryPlatforms.platforms_match(a::ExtendedPlatform{P}, b::ExtendedPlatform{P}) where {P<:Platform} =
    platforms_match(base_platform(a), base_platform(b)) &&  all(a.ext[k] == b.ext[k] for k in keys(a.ext) ∩ keys(b.ext))
# The wrapped platform is the same as the other one: the arguments match if the
# wrapper platform and the other one match
Pkg.BinaryPlatforms.platforms_match(a::ExtendedPlatform{P}, b::P) where {P<:Platform} = platforms_match(base_platform(a), b)
Pkg.BinaryPlatforms.platforms_match(a::P, b::ExtendedPlatform{P}) where {P<:Platform} = platforms_match(a, base_platform(b))
# Extending a platform different from the other one: do not match
Pkg.BinaryPlatforms.platforms_match(a::ExtendedPlatform{P1}, b::P2) where {P1<:Platform, P2<:Platform} = false
Pkg.BinaryPlatforms.platforms_match(a::P1, b::ExtendedPlatform{P2}) where {P1<:Platform, P2<:Platform} = false
# Extending different platforms: do not match
Pkg.BinaryPlatforms.platforms_match(a::ExtendedPlatform{P1}, b::ExtendedPlatform{P2}) where {P1<:Platform, P2<:Platform} = false

Base.:(==)(a::ExtendedPlatform, b::ExtendedPlatform) = base_platform(a) == base_platform(b) && a.ext == b.ext

# This function also strips out the extra features of the type
abi_agnostic(ep::ExtendedPlatform) = abi_agnostic(base_platform(ep))

function Base.show(io::IO, ep::ExtendedPlatform)
    print(io, BinaryPlatforms.platform_name(ep), "(", base_platform(ep))
    length(ep.ext) > 0 && print(io, ";")
    join(io, [" $(k)=$(repr(v))" for (k, v) in ep.ext], ",")
    print(io, ")")
end

function tryparse_standard_platform(machine::AbstractString)
    p = with_logger(NullLogger()) do
        BinaryPlatforms.platform_key_abi(machine)
    end
    if isa(p, UnknownPlatform)
        return nothing
    end
    return p
end

function Base.tryparse(::Type{ExtendedPlatform}, str::AbstractString)
    # Fast-track `AnyPlatform`
    if str == "any"
        return AnyPlatform()
    end
    split_str = split(str, "-")
    idx = findfirst(str -> occursin("+", str), split_str)
    if idx === nothing
        # There are no key-value pairs, parse the entire string with
        # `tryparse_standard_platform`
        return tryparse_standard_platform(str)
    end
    base_platform = tryparse_standard_platform(join(split_str[1:max(1, idx - 1)], '-'))
    if base_platform === nothing
        return nothing
    end
    extra = Dict{String,String}()
    # Build up the extra features
    for kv in split_str[idx:end]
        # Split the extra feature with the delimiter we expect between the key
        # and the value
        key_value = split(kv, '+')
        if length(key_value) != 2
            # The string doesn't represent a key-value pair, give up
            return nothing
        end
        extra[key_value[1]] = key_value[2]
    end
    # Return the extended platform parsed
    ExtendedPlatform(base_platform, extra)
end

function Base.parse(T::Type{ExtendedPlatform}, str::AbstractString)
    parsed = tryparse(T, str)
    if parsed === nothing
        throw(ArgumentError("Cannot parse \"$(str)\" as an $(T)"))
    end
    return parsed
end

function Pkg.Artifacts.pack_platform!(meta::Dict, p::ExtendedPlatform)
    for (k, v) in p.ext
        meta[k] = v
    end
    # We call this method at the end to make extra sure the keys above don't
    # override the default ones
    Artifacts.pack_platform!(meta, base_platform(p))
end

ext: jl


text:
Base.zero(::Type{Union{Int64, VariableRef, GenericAffExpr{Float64,VariableRef}}}) = 0

# Helper function to modify the fairness tensor according to the values for sp2n, on2p, etc
# vals is a 2D array of the form [[sp2n, sn2p], [op2n, on2p]]
function _fairTensorLinProg!(ft::FairTensor, vals)
	mat = deepcopy(ft.mat)
	ft.mat = zeros(Union{VariableRef, Int, GenericAffExpr{Float64,VariableRef}}, size(mat)...)
	for i in 1:length(ft.labels)
		p2n, n2p = vals[i, :] #These vals are VariableRef from library JuMP
		p2p, n2n = 1-p2n, 1-n2p
		a = zeros(Union{VariableRef, Int, GenericAffExpr{Float64,VariableRef}}, 2, 2) # The numbers for modified fairness tensor values for a group
		a[1, 1] = mat[i, 1, 1]*p2p + mat[i, 2, 2]*n2p
		a[1, 2] = mat[i, 1, 2]*p2p + mat[i, 2, 1]*n2p
		a[2, 1] = mat[i, 2, 1]*n2n + mat[i, 1, 1]*p2n
		a[2, 2] = mat[i, 2, 2]*n2n + mat[i, 1, 2]*p2n
		ft.mat[i, :, :] = a
	end
end

"""
    LinProgWrapper

It is a postprocessing algorithm that uses JuMP and Ipopt library to minimise error and satisfy the equality of specified specified measures for all groups at the same time.
Automatic differentiation and gradient based optimisation is used to find probabilities with which the predictions are changed for each group.
"""
mutable struct LinProgWrapper <: DeterministicComposite
	grp::Symbol
	classifier::MLJBase.Model
	measure::Measure
end

"""
    LinProgWrapper(classifier; grp=:class, measure)

Instantiates LinProgWrapper which wraps the classifier and containts the measure to optimised and the sensitive attribute(grp)
"""
function LinProgWrapper(classifier::MLJBase.Model; grp::Symbol=:class, measure::Measure)
	return LinProgWrapper(grp, classifier, measure)
end

function MMI.fit(model::LinProgWrapper, verbosity::Int, X, y)
	grps = X[:, model.grp]
	n = length(levels(grps)) # Number of different values for sensitive attribute

	# As LinProgWrapper is a postprocessing algorithm, the model needs to be fitted first
	mch = machine(model.classifier, X, y)
	fit!(mch)
	ŷ = MMI.predict(mch, X)

	if typeof(ŷ[1]) <: MLJBase.UnivariateFinite
		ŷ = MLJBase.mode.(ŷ)
	end

	ŷ = convert(Array, ŷ) # Incase ŷ is categorical array, convert to normal array to support various operations
	y = convert(Array, y)

	# Finding the probabilities of changing predictions is a Linear Programming Problem
	# JuMP and Ipopt Optimizer are used to for this Linear Programming Problem
	m = JuMP.Model(Ipopt.Optimizer)

	@variable(m, 0<= p2p[1:n] <=1)
	@variable(m, 0<= p2n[1:n] <=1)
	@variable(m, 0<= n2p[1:n] <=1)
	@variable(m, 0<= n2n[1:n] <=1)

	@constraint(m, [i=1:n], p2p[i] == 1 - p2n[i])
	@constraint(m, [i=1:n], n2p[i] == 1 - n2n[i])

	ft = fair_tensor(categorical(ŷ), categorical(y), categorical(grps))

	vals = zeros(Union{VariableRef, Int, GenericAffExpr{Float64,VariableRef}}, n, 2)
	vals[: , 1] = p2n
	vals[: , 2] = n2p

	_fairTensorLinProg!(ft, vals)

	mat = reshape(ft.mat, (4n))
	@variable(m, aux[1:4n])
	@constraint(m,[i=1:4n], mat[i]==aux[i])

	register(m, :fpr, 4n, (x...)->fpr(MLJFair.FairTensor{n}(reshape(collect(x), (n, 2, 2)), ft.labels)), autodiff=true)
	register(m, :fnr, 4n, (x...)->fnr(MLJFair.FairTensor{n}(reshape(collect(x), (n, 2, 2)), ft.labels)), autodiff=true)
	@NLobjective(m, Min, fpr(aux...) + fnr(aux...))

	measure = model.measure
	register(m, :ms, 9, (i, x...)->measure(MLJFair.FairTensor{2}(reshape(collect(x), (n, 2, 2)), ft.labels), grp=levels(grps)[1]), autodiff=true)

	@NLexpression(m, ms[i=1:n], ms(i, aux...))

	@NLconstraint(m, [i=2:n], ms[1]==ms[i])

	optimize!(m)

	fitresult = [[JuMP.value.(p2n), JuMP.value.(n2p)], mch.fitresult]

	return fitresult, nothing, nothing
end

# Corresponds to eq_odds function which uses mix_rates to modify results
function MMI.predict(model::LinProgWrapper, fitresult, Xnew)

	(p2n, n2p), classifier_fitresult = fitresult

	ŷ = MMI.predict(model.classifier, classifier_fitresult, Xnew)

	if typeof(ŷ[1]) <: MLJBase.UnivariateFinite
		ŷ = MLJBase.mode.(ŷ)
	end

	ŷ = convert(Array, ŷ) # Need to convert to normal array as categorical array doesn't support sub
	grps = Xnew[:, model.grp]

	n = length(levels(grps)) # Number of different values for sensitive attribute

	for i in 1:n
		Class = levels(grps)[i]
		Grp = grps .== Class

		pp_indices = shuffle(findall((grps.==Grp) .& (ŷ.==1))) # predicted positive for iᵗʰ class
		pn_indices = shuffle(findall((grps.==Class) .& (ŷ.==0))) # predicted negative for iᵗʰ class

		# Note : arrays in julia start from 1
		p2n_indices = pp_indices[1:convert(Int, floor(length(pp_indices)*p2n[i]))]
		n2p_indices = pn_indices[1:convert(Int, floor(length(pn_indices)*n2p[i]))]

		ŷ[p2n_indices] = 1 .- ŷ[p2n_indices]
		ŷ[n2p_indices] = 1 .- ŷ[n2p_indices]
	end
	return ŷ
end


text:
module SurrogateModels

"""
    regression(X,y,m)

Output a regression matrix given inputs

 - `X`: ``n × k`` matrix with `n` training points in `k` dimensional feature space

 - `y`: ``n × 1`` vector of responses (######)

 - `m`: Order of polynomial (Presently only `1` and `2` is supported)

"""
function regression(x,y,m)

    return(x)
end

end
# vim:filetype=julia:foldmethod=syntax

max_stars_repo_name: devendra-ghate/surrogateModels

max_issues_repo_name: devendra-ghate/surrogateModels

max_forks_repo_name: devendra-ghate/surrogateModels


text:
using FirstOrderSolvers
using LinearAlgebra
using Test
using Random

println("Test: conjugateGradient.jl")
include("conjugateGradient.jl")

println("Test: HSDEAffine.jl")
include("HSDEAffine.jl")

println("Test: affinepluslinear.jl")
include("affinepluslinear.jl")

println("Test: testDRandGAPA.jl")
include("testDRandGAPA.jl")

println("Test: testPSD.jl")
include("testPSD.jl")

println("Test: testfeasibility.jl")
include("testfeasibility.jl")

println("Test: testprint.jl")
include("testprint.jl")

#println("Test: testspecific.jl")
#include("testspecific.jl")

# println("Test: testconvex.jl")
# include("testconvex.jl")


text:
# CodeTable
# =========

struct CodeTable{base}
    # n-bit code => ascii code
    encodeword::Vector{UInt8}

    # ascii code => n-bit code
    decodeword::Vector{UInt8}

    # ascii code for padding
    padcode::UInt8
end

function Base.copy(table::CodeTable{base}) where base
    return CodeTable{base}(
        copy(table.encodeword),
        copy(table.decodeword),
        table.padcode)
end

const whitespace = "\t\n\v\f\r "

function ignorecode end

"""
    ignorechars!(table::CodeTable, asciichars::String)

Add characters that will be ignored while decoding.
"""
function ignorechars!(table::CodeTable, asciichars::String)
    if !isascii(asciichars)
        throw(ArgumentError("ignored characters must be ASCII"))
    end
    for char in asciichars
        code = UInt8(char)
        table.decodeword[code+1] = ignorecode(typeof(table))
    end
    return table
end


text:
function RoboDojo.indices_z(model::PlanarPush)
    nq = model.nq
    nc = model.nc
    q = collect(1:nq)
    γ = collect(nq .+ (1:1))
    sγ = collect(nq + 1 .+ (1:1))
    ψ = collect(nq + 2 .+ (1:5))
    b = collect(nq + 2 + 5 .+ (1:9))
    sψ = collect(nq + 2 + 5 + 9 .+ (1:5))
    sb = collect(nq + 2 + 5 + 9 + 5 .+ (1:9))
    IndicesZ(q, γ, sγ, ψ, b, sψ, sb)
end

RoboDojo.nominal_configuration(model::PlanarPush) = [-1.0; 0.0; 0.0; 0.0; 0.0]

function RoboDojo.indices_optimization(model::PlanarPush)
    nq = model.nq
    nz = num_var(model)
    IndicesOptimization(
        nz,
        nz,
        [collect(nq .+ (1:1)), collect(nq + 1 .+ (1:1))],
        [collect(nq .+ (1:1)), collect(nq + 1 .+ (1:1))],
        [
         [collect([collect(nq + 2 .+ (1:1)); collect(nq + 2 + 5 .+ (1:2))]), collect([collect(nq + 2 + 5 + 9 .+ (1:1)); collect(nq + 2 + 5 + 9 + 5 .+ (1:2))])],
         [collect([collect(nq + 2 + 1 .+ (1:1)); collect(nq + 2 + 5 + 2 .+ (1:2))]), collect([collect(nq + 2 + 5 + 9 + 1 .+ (1:1)); collect(nq + 2 + 5 + 9 + 5 + 2 .+ (1:2))])],
         [collect([collect(nq + 2 + 2 .+ (1:1)); collect(nq + 2 + 5 + 4 .+ (1:2))]), collect([collect(nq + 2 + 5 + 9 + 2 .+ (1:1)); collect(nq + 2 + 5 + 9 + 5 + 4 .+ (1:2))])],
         [collect([collect(nq + 2 + 3 .+ (1:1)); collect(nq + 2 + 5 + 6 .+ (1:2))]), collect([collect(nq + 2 + 5 + 9 + 3 .+ (1:1)); collect(nq + 2 + 5 + 9 + 5 + 6 .+ (1:2))])],
         [collect([collect(nq + 2 + 4 .+ (1:1)); collect(nq + 2 + 5 + 8 .+ (1:1))]), collect([collect(nq + 2 + 5 + 9 + 4 .+ (1:1)); collect(nq + 2 + 5 + 9 + 5 + 8 .+ (1:1))])],
        ],
        [
         [collect([collect(nq + 2 .+ (1:1)); collect(nq + 2 + 5 .+ (1:2))]), collect([collect(nq + 2 + 5 + 9 .+ (1:1)); collect(nq + 2 + 5 + 9 + 5 .+ (1:2))])],
         [collect([collect(nq + 2 + 1 .+ (1:1)); collect(nq + 2 + 5 + 2 .+ (1:2))]), collect([collect(nq + 2 + 5 + 9 + 1 .+ (1:1)); collect(nq + 2 + 5 + 9 + 5 + 2 .+ (1:2))])],
         [collect([collect(nq + 2 + 2 .+ (1:1)); collect(nq + 2 + 5 + 4 .+ (1:2))]), collect([collect(nq + 2 + 5 + 9 + 2 .+ (1:1)); collect(nq + 2 + 5 + 9 + 5 + 4 .+ (1:2))])],
         [collect([collect(nq + 2 + 3 .+ (1:1)); collect(nq + 2 + 5 + 6 .+ (1:2))]), collect([collect(nq + 2 + 5 + 9 + 3 .+ (1:1)); collect(nq + 2 + 5 + 9 + 5 + 6 .+ (1:2))])],
         [collect([collect(nq + 2 + 4 .+ (1:1)); collect(nq + 2 + 5 + 8 .+ (1:1))]), collect([collect(nq + 2 + 5 + 9 + 4 .+ (1:1)); collect(nq + 2 + 5 + 9 + 5 + 8 .+ (1:1))])],
        ],
        collect(1:(nq + 15)),
        collect(nq + 15 .+ (1:1)),
        collect(nq + 15 + 1 .+ (1:14)),
        [
         collect(nq + 15 + 1 .+ (1:3)),
         collect(nq + 15 + 4 .+ (1:3)),
         collect(nq + 15 + 7 .+ (1:3)),
         collect(nq + 15 + 10 .+ (1:3)),
         collect(nq + 15 + 13 .+ (1:2)),
        ],
        collect(nq + 15 .+ (1:15))
        )
end

function RoboDojo.initialize_z!(z, model::PlanarPush, idx::IndicesZ, q)
    z[idx.q] .= q
	z[idx.γ] .= 1.0
	z[idx.sγ] .= 1.0
    z[idx.ψ] .= 1.0
    z[idx.b] .= 0.1
    z[idx.sψ] .= 1.0
    z[idx.sb] .= 0.1
end

num_var(model::PlanarPush) = model.nq + 2 * 1 + 2 * 14
friction_coefficients(model::PlanarPush{T}) where T = T[]


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

using Dash
using SyntheticDatasetsDashboard

run_server(SyntheticDatasetsDashboard.app, "0.0.0.0", 4000, debug = true)


text:
############################################################
# Linked list with last and Nothing
############################################################

mutable struct Orbit2{T, S} <: AbstractOrbit{T,S}
    pt::T # starting point
    last::Tuple{T, Tuple{S, Nothing}} # idx -> (content, nothing)
    elts::Dict{T, Tuple{S, T}} # idx -> (content, nextptr)
end

function Orbit2(pt::T, val::S) where {T,S}
    return Orbit2(pt, (pt, (val, nothing)), Dict{T, Tuple{S, T}}())
end

Orbit2(pt::T) where {T} = Orbit2(pt, nothing)

@inline Base.in(x, orb::Orbit2) = haskey(orb.elts, x) || x == orb.last[1]

@inline function Base.push!(orb::Orbit2{T,S}, tup::Tuple{T,S}) where {T,S}
    o, val = tup
    orb.elts[first(orb.last)] = (first(last(orb.last)), o)
    orb.last = (o, (val, nothing))
    return orb
end

@inline Base.push!(orb::Orbit2{T,Nothing}, n::T) where T = push!(orb, (n,nothing))

@inline islast(orb::Orbit2, o) = o == first(orb.last)
@inline next(orb::Orbit2, s) = (last(orb.elts[s]), last(orb.elts[s]))

# o is a point in orbit, return (value, nextptr)
@inline Base.getindex(orb::Orbit2, o) = (islast(orb, o) ? first(last(orb.last)) : first(orb.elts[o]))

@inline Base.iterate(orb::Orbit2) = orb.pt, orb.pt
@inline Base.iterate(orb::Orbit2, s) = (islast(orb, s) ? nothing : next(orb, s))
@inline Base.length(orb::Orbit2) = length(orb.elts) + 1

@inline function Base.:(==)(o1::Orbit2, o2::Orbit2)
    o1.pt == o2.pt && o1.last == o2.last || return false
    return o1.elts == o2.elts
end

@inline Base.first(orb::Orbit2) = orb.pt


text:
using Flight
using Test

include("test_quaternions.jl")
include("test_attitude.jl")
include("test_geodesy.jl")
# include("test_kinematics.jl")

using .TestQuaternions
using .TestAttitude
using .TestGeodesy
# using .TestKinematics

# test_quaternions()
# test_attitude()
test_geodesy()
# test_kinematics()


text:
abstract Element

type Element1d{T <: Number} <: Element
    id::Int
    a::T
    b::T
    ξ::Vector{T}
    w::Vector{T}
    D::Matrix{T}
    x::Vector{T}
    J::Vector{T}
    wJ::Vector{T}
    dξdx::Vector{T}
end

function Element1d{T<:Number}(id, a::T, b::T, bas::GenBasis1d)
    w = qweights(bas)
    ξ = qnodes(bas)
    Q = nquad(bas)
    x = zeros(T, Q)
    dξdx = zeros(T,Q)
    J = zeros(T,Q)
    wJ = zeros(T,Q)
    D = diffmat(bas)
    if !isinf(a) && !isinf(b)
        d = (b-a) / 2

        for i = 1:Q
            J[i] = d
            x[i] = (one(T)-ξ[i])*a/2 + (one(T) + ξ[i])*b/2
            dξdx[i] = one(T)/d
            wJ[i] = w[i] * d
        end
    end

    Element1d(id, a, b, ξ, w, D, x, J, wJ, dξdx)
end

eid(e::Element) = e.id
jacweights(e::Element) = e.wJ
deriv_ξ(e::Element1d) = e.dξdx
jacobian(el) = el.J
diffmat(e::Element1d) = e.D

project(el::Element1d, f::AbstractVector) = project(basis1d(el), f)
project(el::Element1d, f::Function) = project(basis1d(el), qnodes(el))


text:
# © 2016 Massachusetts Institute of Technology.  See LICENSE file for details.
immutable TemplateIterator
  type_params::Vector{Symbol}
  types::Vector{Vector{Symbol}}
end

TemplateIterator(t::Vector) =
  TemplateIterator(Symbol[i[1] for i in t], Vector{Symbol}[Symbol[i[2:end]...] for i in t])

Base.start(i::TemplateIterator) = ones(Int, length(i.type_params))
Base.done(i::TemplateIterator, s::Vector{Int}) = s[end] > length(i.types[end])
function Base.next(i::TemplateIterator, s::Vector{Int})
  s = copy(s)
  item = @compat Dict{Symbol,Symbol}(i.type_params[j] => i.types[j][s[j]] for j in 1:length(s))
  s[1] += 1
  for j in 1:length(s)-1
    if s[j] > length(i.types[j])
      s[j] = 1
      s[j+1] += 1
    end
  end
  item,s
end

hexstring(x::AbstractString) = x[1:6]
hexstring(x::AbstractArray{UInt8}) = join(map(x->hex(x,2), x[1:3]),"")

rsym(ex::Symbol, d::Dict{Symbol,Symbol}) = get(d, ex, ex)
rsym(ex::Expr, d::Dict{Symbol,Symbol}) = Expr(ex.head, map(x->rsym(x, d), ex.args)...)
rsym(t::Tuple, d::Dict{Symbol,Symbol}) = rsym(t[1], d), t[2]

type_names(templates, d::Dict{Symbol,Symbol}) = join([d[i[1]] for i in templates], "_")
replace_type_parameters(signature, d::Dict{Symbol,Symbol}) = map(t->rsym(t, d), signature)

function old_templates(templates::Expr)
  @assert templates.head == :vect
  for i in 1:length(templates.args)
    @assert templates.args[i].head == :tuple
  end
  [(a.args...) for a in templates.args]
end

function curly_templates(x::Expr)
  @assert x.head == :curly
  templates = sizehint!(Tuple[], length(x.args)-1)
  for i in 2:length(x.args)
    @assert isa(x.args[i], Expr) && x.args[i].head == :<:
    @assert isa(x.args[i].args[1], Symbol)

    if x.args[i].args[2] == :Real
      push!(templates, (x.args[i].args[1], :Cfloat, :Cdouble))
    elseif isa(x.args[i].args[2], Expr) && x.args[i].args[2].head == :curly && x.args[i].args[2].args[1] == :Union
      push!(templates, (x.args[i].args[1], x.args[i].args[2].args[2:end]...))
    else
      error("Invalid cuda_kernel template argument: $(x.args[i])")
    end
  end
  return templates
end

macro cuda_kernel(funcall, va...)
  @assert funcall.head == :call
  for i in 2:length(funcall.args)
    @assert funcall.args[i].head == :(::)
  end
  signature = map(x->(x.args[2], x.args[1]), funcall.args[2:end])

  if isa(funcall.args[1], Expr) && funcall.args[1].head == :curly
    @assert length(va) == 1
    @assert isa(funcall.args[1].args[1], Symbol)
    name = string(funcall.args[1].args[1])
    templates = curly_templates(funcall.args[1])
    text = va[1]
  elseif isa(funcall.args[1], Symbol)
    @assert length(va) == 2
    name = string(funcall.args[1])
    templates = old_templates(va[1])
    text = va[2]
  else
    error("Invalid cuda template")
  end

  cuda_kernel(name, signature, templates, eval(text))
end

macro cuda_gsl(funcall, text)
  quote
    @cuda_kernel($funcall, """
  int i;
  for (i = blockIdx.x*blockDim.x + threadIdx.x; i < n; i += blockDim.x*gridDim.x) {
    $($(esc(text)));
  }""")
  end
end


text:
# #  Portfolio Optimization
#
# In this problem, we will find the portfolio allocation that minimizes risk while achieving a given expected return $R_\text{target}$.
#
# Suppose that we know the mean returns $\mu \in \mathbf{R}^n$ and the covariance $\Sigma \in \mathbf{R}^{n \times n}$ of the $n$ assets. We would like to find a portfolio allocation $w \in \mathbf{R}^n$, $\sum_i w_i = 1$, minimizing the *risk* of the portfolio, which we measure as the variance $w^T \Sigma w$ of the portfolio. The requirement that the portfolio allocation achieve the target expected return can be expressed as $w^T \mu >= R_\text{target}$. We suppose further that our portfolio allocation must comply with some lower and upper bounds on the allocation, $w_\text{lower} \leq w \leq w_\text{upper}$.
#
# This problem can be written as
#
# $$
# \begin{array}{ll}
#     \text{minimize}   & w^T \Sigma w \\
#     \text{subject to} & w^T \mu >= R_\text{target} \\
#                       & \sum_i w_i = 1 \\
#                       & w_\text{lower} \leq w \leq w_\text{upper}
# \end{array}
# $$
#
# where $w \in \mathbf{R}^n$ is our optimization variable.

using Convex, SCS

## generate problem data
μ = [11.5; 9.5; 6]/100          #expected returns
Σ  = [166  34  58;              #covariance matrix
       34  64   4;
       58   4 100]/100^2

n = length(μ)                   #number of assets

R_target = 0.1
w_lower = 0
w_upper = 0.5;

# If you want to try the optimization with more assets, uncomment and run the next cell. It creates a vector or average returns and a variance-covariance matrix that have scales similar to the numbers above.

#=
using Random
Random.seed!(123)

n = 15                                      #number of assets, CHANGE IT?

μ = (6 .+ (11.5-6)*rand(n))/100             #mean
A = randn(n,n)
Σ = (A * A' + diagm(0=>rand(n)))/500;       #covariance matrix
=#

#-

w    = Variable(n)
ret  = dot(w,μ)
risk = quadform(w,Σ)

p = minimize( risk,
              ret >= R_target,
              sum(w) == 1,
              w_lower <= w,
              w <= w_upper )

solve!(p, SCS.Optimizer())     #use SCS.Optimizer(verbose = false) to suppress printing

#-

# Optimal portfolio weights:
w.value

#-

sum(w.value)


text:
abstract AbstractBactrian{F<:Distributions.VariateForm} <: Distributions.ContinuousDistribution{F}

type Bactrian{T<:AbstractFloat} <: AbstractBactrian{Distributions.Univariate}
    mixture::Distributions.UnivariateMixture
    μ::T
    σ::T
    m::T
end

@inline _bactrianscale(::Type{Val{:normal}},s::AbstractFloat,m::AbstractFloat) = s*sqrt(1-m*m)
@inline _bactrianscale(::Type{Val{:laplace}},s::AbstractFloat,m::AbstractFloat) = s*sqrt(sqrt(2)*(1-m*m))
@inline _bactrianscale(::Type{Val{:triangular}},s::AbstractFloat,m::AbstractFloat) = s*sqrt(6*(1-m*m))

@inline _bactrianscale(d::Distributions.Normal,s::AbstractFloat,m::AbstractFloat) = _bactrianscale(Val{:normal},s,m)
@inline _bactrianscale(d::Distributions.Laplace,s::AbstractFloat,m::AbstractFloat) = _bactrianscale(Val{:laplace},s,m)
@inline _bactrianscale(d::Distributions.SymTriangularDist,s::AbstractFloat,m::AbstractFloat) = _bactrianscale(Val{:triangular},s,m)

@inline function _mixturemodel(subtype::Symbol,x::AbstractFloat,s::AbstractFloat,m::AbstractFloat)
    bs = _bactrianscale(Val{subtype},s,m)
    Distributions.MixtureModel([_distribution(Val{subtype},x-m*s,bs),_distribution(Val{subtype},x+m*s,bs)],[1/2,1/2])
end

@inline function _distribution(::Type{Val{:bactrian}},x::AbstractFloat,s::AbstractFloat,subtype::Symbol,mixing::AbstractFloat)
    Bactrian{typeof(x)}(_mixturemodel(subtype,x,s,mixing),x,s,mixing)
end

function recenter(b::Bactrian,x)
    b.μ = x
    b.mixture.components[1] = recenter(b.mixture.components[1],x-b.m*b.σ)
    b.mixture.components[2] = recenter(b.mixture.components[2],x+b.m*b.σ)
    b
end

function rescale(b::Bactrian,s)
    b.σ = s*b.σ
    bs = _bactrianscale(b.mixture.components[1],b.σ,b.m)
    b.mixture.components[1] = update(b.mixture.components[1],b.μ-b.m*b.σ,bs)
    b.mixture.components[2] = update(b.mixture.components[2],b.μ+b.m*b.σ,bs)
    b
end

function update(b::Bactrian,x,s)
    b.μ = x
    b.σ = s
    bs = _bactrianscale(b.mixture.components[1],s,b.m)
    b.mixture.components[1] = update(b.mixture.components[1],x-b.m*s,bs)
    b.mixture.components[2] = update(b.mixture.components[2],x+b.m*s,bs)
    b
end

rand(b::Bactrian) = rand(b.mixture)
rand!(b::Bactrian,x::AbstractArray) = rand!(b.mixture,x)
pdf(b::Bactrian,x::Real) = pdf(b.mixture,x)

mean(b::Bactrian) = mean(b.mixture)
var(b::Bactrian) = var(b.mixture)
scale(b::Bactrian) = b.σ


text:
### routines related to geometric transforms of a set of coordinates.

function shiftthenstretch(x,n::Int,T,N)
    return (x-n*T)/N
end

function shiftthencompress(x,n::Int,T,N)
    return (x-n*T)*N
end

# evaluates f(x/M)
function evalstretchedsignal(x, f::Function, M::Int)
    return f(x/M)
end

"""
    convertcompactdomain(x::T, a::T, b::T, c::T, d::T)::T

converts compact domain x ∈ [a,b] to compact domain out ∈ [c,d].
"""
function convertcompactdomain(x::T, a::T, b::T, c::T, d::T)::T where T <: Real

    return (x-a)*(d-c)/(b-a)+c
end

function convertcompactdomain(x::Vector{T}, a::Vector{T}, b::Vector{T}, c::Vector{T}, d::Vector{T})::Vector{T} where T <: Real

    return collect( convertcompactdomain(x[i], a[i], b[i], c[i], d[i]) for i = 1:length(x) )
end

max_stars_repo_name: RoyCCWang/RWJuliaUtilities

max_issues_repo_name: RoyCCWang/RWJuliaUtilities

max_forks_repo_name: RoyCCWang/RWJuliaUtilities


text:
# Julia wrapper for header: p8est.h
# Automatically generated using Clang.jl

function p8est_memory_used()
    ccall((:p8est_memory_used, p4est_lib), Cint, ())
end

function p8est_revision(p8est)
    ccall((:p8est_revision, p4est_lib), Clong, (Ptr{p8est_t},), p8est)
end

function p8est_qcoord_to_vertex(connectivity, treeid, x, y, z, vxyz)
    ccall((:p8est_qcoord_to_vertex, p4est_lib), Cvoid, (Ptr{p8est_connectivity_t}, p4est_topidx_t, p4est_qcoord_t, p4est_qcoord_t, p4est_qcoord_t, Ptr{Cdouble}), connectivity, treeid, x, y, z, vxyz)
end

function p8est_new(mpicomm, connectivity, data_size, init_fn, user_pointer)
    ccall((:p8est_new, p4est_lib), Ptr{p8est_t}, (MPI_Comm, Ptr{p8est_connectivity_t}, Csize_t, p8est_init_t, Ptr{Cvoid}), mpicomm, connectivity, data_size, init_fn, user_pointer)
end

function p8est_destroy(p8est)
    ccall((:p8est_destroy, p4est_lib), Cvoid, (Ptr{p8est_t},), p8est)
end

function p8est_copy(input, copy_data)
    ccall((:p8est_copy, p4est_lib), Ptr{p8est_t}, (Ptr{p8est_t}, Cint), input, copy_data)
end

function p8est_reset_data(p8est, data_size, init_fn, user_pointer)
    ccall((:p8est_reset_data, p4est_lib), Cvoid, (Ptr{p8est_t}, Csize_t, p8est_init_t, Ptr{Cvoid}), p8est, data_size, init_fn, user_pointer)
end

function p8est_refine(p8est, refine_recursive, refine_fn, init_fn)
    ccall((:p8est_refine, p4est_lib), Cvoid, (Ptr{p8est_t}, Cint, p8est_refine_t, p8est_init_t), p8est, refine_recursive, refine_fn, init_fn)
end

function p8est_coarsen(p8est, coarsen_recursive, coarsen_fn, init_fn)
    ccall((:p8est_coarsen, p4est_lib), Cvoid, (Ptr{p8est_t}, Cint, p8est_coarsen_t, p8est_init_t), p8est, coarsen_recursive, coarsen_fn, init_fn)
end

function p8est_balance(p8est, btype, init_fn)
    ccall((:p8est_balance, p4est_lib), Cvoid, (Ptr{p8est_t}, p8est_connect_type_t, p8est_init_t), p8est, btype, init_fn)
end

function p8est_partition(p8est, allow_for_coarsening, weight_fn)
    ccall((:p8est_partition, p4est_lib), Cvoid, (Ptr{p8est_t}, Cint, p8est_weight_t), p8est, allow_for_coarsening, weight_fn)
end

function p8est_checksum(p8est)
    ccall((:p8est_checksum, p4est_lib), UInt32, (Ptr{p8est_t},), p8est)
end

function p8est_save(filename, p8est, save_data)
    ccall((:p8est_save, p4est_lib), Cvoid, (Cstring, Ptr{p8est_t}, Cint), filename, p8est, save_data)
end

function p8est_load(filename, mpicomm, data_size, load_data, user_pointer, connectivity)
    ccall((:p8est_load, p4est_lib), Ptr{p8est_t}, (Cstring, MPI_Comm, Csize_t, Cint, Ptr{Cvoid}, Ptr{Ptr{p8est_connectivity_t}}), filename, mpicomm, data_size, load_data, user_pointer, connectivity)
end
# Julia wrapper for header: p8est_bits.h
# Automatically generated using Clang.jl

function p8est_quadrant_print(log_priority, q)
    ccall((:p8est_quadrant_print, p4est_lib), Cvoid, (Cint, Ptr{p8est_quadrant_t}), log_priority, q)
end

function p8est_quadrant_is_equal(q1, q2)
    ccall((:p8est_quadrant_is_equal, p4est_lib), Cint, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}), q1, q2)
end

function p8est_quadrant_overlaps(q1, q2)
    ccall((:p8est_quadrant_overlaps, p4est_lib), Cint, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}), q1, q2)
end

function p8est_quadrant_is_equal_piggy(q1, q2)
    ccall((:p8est_quadrant_is_equal_piggy, p4est_lib), Cint, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}), q1, q2)
end

function p8est_quadrant_compare(v1, v2)
    ccall((:p8est_quadrant_compare, p4est_lib), Cint, (Ptr{Cvoid}, Ptr{Cvoid}), v1, v2)
end

function p8est_quadrant_disjoint(v1, v2)
    ccall((:p8est_quadrant_disjoint, p4est_lib), Cint, (Ptr{Cvoid}, Ptr{Cvoid}), v1, v2)
end

function p8est_quadrant_compare_piggy(v1, v2)
    ccall((:p8est_quadrant_compare_piggy, p4est_lib), Cint, (Ptr{Cvoid}, Ptr{Cvoid}), v1, v2)
end

function p8est_quadrant_compare_local_num(v1, v2)
    ccall((:p8est_quadrant_compare_local_num, p4est_lib), Cint, (Ptr{Cvoid}, Ptr{Cvoid}), v1, v2)
end

function p8est_quadrant_equal_fn(v1, v2, u)
    ccall((:p8est_quadrant_equal_fn, p4est_lib), Cint, (Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}), v1, v2, u)
end

function p8est_quadrant_hash_fn(v, u)
    ccall((:p8est_quadrant_hash_fn, p4est_lib), UInt32, (Ptr{Cvoid}, Ptr{Cvoid}), v, u)
end

function p8est_node_equal_piggy_fn(v1, v2, u)
    ccall((:p8est_node_equal_piggy_fn, p4est_lib), Cint, (Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}), v1, v2, u)
end

function p8est_node_hash_piggy_fn(v, u)
    ccall((:p8est_node_hash_piggy_fn, p4est_lib), UInt32, (Ptr{Cvoid}, Ptr{Cvoid}), v, u)
end

function p8est_node_clamp_inside(n, r)
    ccall((:p8est_node_clamp_inside, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}), n, r)
end

function p8est_node_unclamp(n)
    ccall((:p8est_node_unclamp, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t},), n)
end

function p8est_node_to_quadrant(n, level, q)
    ccall((:p8est_node_to_quadrant, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Cint, Ptr{p8est_quadrant_t}), n, level, q)
end

function p8est_quadrant_contains_node(q, n)
    ccall((:p8est_quadrant_contains_node, p4est_lib), Cint, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}), q, n)
end

function p8est_quadrant_ancestor_id(q, level)
    ccall((:p8est_quadrant_ancestor_id, p4est_lib), Cint, (Ptr{p8est_quadrant_t}, Cint), q, level)
end

function p8est_quadrant_child_id(q)
    ccall((:p8est_quadrant_child_id, p4est_lib), Cint, (Ptr{p8est_quadrant_t},), q)
end

function p8est_quadrant_is_inside_root(q)
    ccall((:p8est_quadrant_is_inside_root, p4est_lib), Cint, (Ptr{p8est_quadrant_t},), q)
end

function p8est_quadrant_is_inside_3x3(q)
    ccall((:p8est_quadrant_is_inside_3x3, p4est_lib), Cint, (Ptr{p8est_quadrant_t},), q)
end

function p8est_quadrant_is_outside_face(q)
    ccall((:p8est_quadrant_is_outside_face, p4est_lib), Cint, (Ptr{p8est_quadrant_t},), q)
end

function p8est_quadrant_is_outside_edge(q)
    ccall((:p8est_quadrant_is_outside_edge, p4est_lib), Cint, (Ptr{p8est_quadrant_t},), q)
end

function p8est_quadrant_is_outside_edge_extra(q, edge)
    ccall((:p8est_quadrant_is_outside_edge_extra, p4est_lib), Cint, (Ptr{p8est_quadrant_t}, Ptr{Cint}), q, edge)
end

function p8est_quadrant_is_outside_corner(q)
    ccall((:p8est_quadrant_is_outside_corner, p4est_lib), Cint, (Ptr{p8est_quadrant_t},), q)
end

function p8est_quadrant_is_node(q, inside)
    ccall((:p8est_quadrant_is_node, p4est_lib), Cint, (Ptr{p8est_quadrant_t}, Cint), q, inside)
end

function p8est_quadrant_is_valid(q)
    ccall((:p8est_quadrant_is_valid, p4est_lib), Cint, (Ptr{p8est_quadrant_t},), q)
end

function p8est_quadrant_is_extended(q)
    ccall((:p8est_quadrant_is_extended, p4est_lib), Cint, (Ptr{p8est_quadrant_t},), q)
end

function p8est_quadrant_is_sibling(q1, q2)
    ccall((:p8est_quadrant_is_sibling, p4est_lib), Cint, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}), q1, q2)
end

function p8est_quadrant_child(q, r, child_id)
    ccall((:p8est_quadrant_child, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Cint), q, r, child_id)
end

function p8est_quadrant_is_sibling_D(q1, q2)
    ccall((:p8est_quadrant_is_sibling_D, p4est_lib), Cint, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}), q1, q2)
end

function p8est_quadrant_is_family(q0, q1, q2, q3, q4, q5, q6, q7)
    ccall((:p8est_quadrant_is_family, p4est_lib), Cint, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}), q0, q1, q2, q3, q4, q5, q6, q7)
end

function p8est_quadrant_is_familyv(q)
    ccall((:p8est_quadrant_is_familyv, p4est_lib), Cint, (Ptr{p8est_quadrant_t},), q)
end

function p8est_quadrant_is_familypv(q)
    ccall((:p8est_quadrant_is_familypv, p4est_lib), Cint, (Ptr{Ptr{p8est_quadrant_t}},), q)
end

function p8est_quadrant_is_parent(q, r)
    ccall((:p8est_quadrant_is_parent, p4est_lib), Cint, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}), q, r)
end

function p8est_quadrant_is_parent_D(q, r)
    ccall((:p8est_quadrant_is_parent_D, p4est_lib), Cint, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}), q, r)
end

function p8est_quadrant_is_ancestor(q, r)
    ccall((:p8est_quadrant_is_ancestor, p4est_lib), Cint, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}), q, r)
end

function p8est_quadrant_is_ancestor_D(q, r)
    ccall((:p8est_quadrant_is_ancestor_D, p4est_lib), Cint, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}), q, r)
end

function p8est_quadrant_is_next(q, r)
    ccall((:p8est_quadrant_is_next, p4est_lib), Cint, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}), q, r)
end

function p8est_quadrant_is_next_D(q, r)
    ccall((:p8est_quadrant_is_next_D, p4est_lib), Cint, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}), q, r)
end

function p8est_quadrant_overlaps_tree(tree, q)
    ccall((:p8est_quadrant_overlaps_tree, p4est_lib), Cint, (Ptr{p8est_tree_t}, Ptr{p8est_quadrant_t}), tree, q)
end

function p8est_quadrant_is_inside_tree(tree, q)
    ccall((:p8est_quadrant_is_inside_tree, p4est_lib), Cint, (Ptr{p8est_tree_t}, Ptr{p8est_quadrant_t}), tree, q)
end

function p8est_quadrant_is_first_last(f, l, a)
    ccall((:p8est_quadrant_is_first_last, p4est_lib), Cint, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}), f, l, a)
end

function p8est_quadrant_enlarge_first(a, q)
    ccall((:p8est_quadrant_enlarge_first, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}), a, q)
end

function p8est_quadrant_enlarge_last(a, q)
    ccall((:p8est_quadrant_enlarge_last, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}), a, q)
end

function p8est_quadrant_ancestor(q, level, r)
    ccall((:p8est_quadrant_ancestor, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Cint, Ptr{p8est_quadrant_t}), q, level, r)
end

function p8est_quadrant_parent(q, r)
    ccall((:p8est_quadrant_parent, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}), q, r)
end

function p8est_quadrant_sibling(q, r, sibling_id)
    ccall((:p8est_quadrant_sibling, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Cint), q, r, sibling_id)
end

function p8est_quadrant_face_neighbor(q, face, r)
    ccall((:p8est_quadrant_face_neighbor, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Cint, Ptr{p8est_quadrant_t}), q, face, r)
end

function p8est_quadrant_face_neighbor_extra(q, t, face, r, nface, conn)
    ccall((:p8est_quadrant_face_neighbor_extra, p4est_lib), p4est_locidx_t, (Ptr{p8est_quadrant_t}, p4est_topidx_t, Cint, Ptr{p8est_quadrant_t}, Ptr{Cint}, Ptr{p8est_connectivity_t}), q, t, face, r, nface, conn)
end

function p8est_quadrant_half_face_neighbors(q, face, n, nur)
    ccall((:p8est_quadrant_half_face_neighbors, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Cint, Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}), q, face, n, nur)
end

function p8est_quadrant_all_face_neighbors(q, face, n)
    ccall((:p8est_quadrant_all_face_neighbors, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Cint, Ptr{p8est_quadrant_t}), q, face, n)
end

function p8est_quadrant_edge_neighbor(q, edge, r)
    ccall((:p8est_quadrant_edge_neighbor, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Cint, Ptr{p8est_quadrant_t}), q, edge, r)
end

function p8est_quadrant_edge_neighbor_extra(q, t, edge, quads, treeids, nedges, conn)
    ccall((:p8est_quadrant_edge_neighbor_extra, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, p4est_locidx_t, Cint, Ptr{sc_array_t}, Ptr{sc_array_t}, Ptr{sc_array_t}, Ptr{p8est_connectivity_t}), q, t, edge, quads, treeids, nedges, conn)
end

function p8est_quadrant_corner_neighbor(q, corner, r)
    ccall((:p8est_quadrant_corner_neighbor, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Cint, Ptr{p8est_quadrant_t}), q, corner, r)
end

function p8est_quadrant_corner_neighbor_extra(q, t, corner, quads, treeids, ncorners, conn)
    ccall((:p8est_quadrant_corner_neighbor_extra, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, p4est_locidx_t, Cint, Ptr{sc_array_t}, Ptr{sc_array_t}, Ptr{sc_array_t}, Ptr{p8est_connectivity_t}), q, t, corner, quads, treeids, ncorners, conn)
end

function p8est_quadrant_half_corner_neighbor(q, corner, r)
    ccall((:p8est_quadrant_half_corner_neighbor, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Cint, Ptr{p8est_quadrant_t}), q, corner, r)
end

function p8est_quadrant_corner_node(q, corner, r)
    ccall((:p8est_quadrant_corner_node, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Cint, Ptr{p8est_quadrant_t}), q, corner, r)
end

function p8est_quadrant_children(q, c0, c1, c2, c3, c4, c5, c6, c7)
    ccall((:p8est_quadrant_children, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}), q, c0, c1, c2, c3, c4, c5, c6, c7)
end

function p8est_quadrant_childrenv(q, c)
    ccall((:p8est_quadrant_childrenv, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}), q, c)
end

function p8est_quadrant_childrenpv(q, c)
    ccall((:p8est_quadrant_childrenpv, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Ptr{Ptr{p8est_quadrant_t}}), q, c)
end

function p8est_quadrant_first_descendant(q, fd, level)
    ccall((:p8est_quadrant_first_descendant, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Cint), q, fd, level)
end

function p8est_quadrant_last_descendant(q, ld, level)
    ccall((:p8est_quadrant_last_descendant, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Cint), q, ld, level)
end

function p8est_quadrant_corner_descendant(q, r, c, level)
    ccall((:p8est_quadrant_corner_descendant, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Cint, Cint), q, r, c, level)
end

function p8est_nearest_common_ancestor(q1, q2, r)
    ccall((:p8est_nearest_common_ancestor, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}), q1, q2, r)
end

function p8est_nearest_common_ancestor_D(q1, q2, r)
    ccall((:p8est_nearest_common_ancestor_D, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}), q1, q2, r)
end

function p8est_quadrant_transform_face(q, r, ftransform)
    ccall((:p8est_quadrant_transform_face, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Ptr{Cint}), q, r, ftransform)
end

function p8est_quadrant_touches_edge(q, edge, inside)
    ccall((:p8est_quadrant_touches_edge, p4est_lib), Cint, (Ptr{p8est_quadrant_t}, Cint, Cint), q, edge, inside)
end

function p8est_quadrant_transform_edge(q, r, ei, et, inside)
    ccall((:p8est_quadrant_transform_edge, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Ptr{p8est_edge_info_t}, Ptr{p8est_edge_transform_t}, Cint), q, r, ei, et, inside)
end

function p8est_quadrant_shift_edge(q, r, rup, rdown, edge)
    ccall((:p8est_quadrant_shift_edge, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Cint), q, r, rup, rdown, edge)
end

function p8est_quadrant_touches_corner(q, corner, inside)
    ccall((:p8est_quadrant_touches_corner, p4est_lib), Cint, (Ptr{p8est_quadrant_t}, Cint, Cint), q, corner, inside)
end

function p8est_quadrant_transform_corner(r, corner, inside)
    ccall((:p8est_quadrant_transform_corner, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Cint, Cint), r, corner, inside)
end

function p8est_quadrant_shift_corner(q, r, corner)
    ccall((:p8est_quadrant_shift_corner, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Cint), q, r, corner)
end

function p8est_quadrant_linear_id(quadrant, level)
    ccall((:p8est_quadrant_linear_id, p4est_lib), UInt64, (Ptr{p8est_quadrant_t}, Cint), quadrant, level)
end

function p8est_quadrant_set_morton(quadrant, level, id)
    ccall((:p8est_quadrant_set_morton, p4est_lib), Cvoid, (Ptr{p8est_quadrant_t}, Cint, UInt64), quadrant, level, id)
end
# Julia wrapper for header: p8est_connectivity.h
# Automatically generated using Clang.jl

function p8est_connect_type_int(btype)
    ccall((:p8est_connect_type_int, p4est_lib), Cint, (p8est_connect_type_t,), btype)
end

function p8est_connect_type_string(btype)
    ccall((:p8est_connect_type_string, p4est_lib), Cstring, (p8est_connect_type_t,), btype)
end

function p8est_connectivity_memory_used()
    ccall((:p8est_connectivity_memory_used, p4est_lib), Cint, ())
end

function p8est_connectivity_face_neighbor_corner_set(c, f, nf, set)
    ccall((:p8est_connectivity_face_neighbor_corner_set, p4est_lib), Cint, (Cint, Cint, Cint, Cint), c, f, nf, set)
end

function p8est_connectivity_face_neighbor_face_corner(fc, f, nf, o)
    ccall((:p8est_connectivity_face_neighbor_face_corner, p4est_lib), Cint, (Cint, Cint, Cint, Cint), fc, f, nf, o)
end

function p8est_connectivity_face_neighbor_corner(c, f, nf, o)
    ccall((:p8est_connectivity_face_neighbor_corner, p4est_lib), Cint, (Cint, Cint, Cint, Cint), c, f, nf, o)
end

function p8est_connectivity_face_neighbor_face_edge(fe, f, nf, o)
    ccall((:p8est_connectivity_face_neighbor_face_edge, p4est_lib), Cint, (Cint, Cint, Cint, Cint), fe, f, nf, o)
end

function p8est_connectivity_face_neighbor_edge(e, f, nf, o)
    ccall((:p8est_connectivity_face_neighbor_edge, p4est_lib), Cint, (Cint, Cint, Cint, Cint), e, f, nf, o)
end

function p8est_connectivity_edge_neighbor_edge_corner(ec, o)
    ccall((:p8est_connectivity_edge_neighbor_edge_corner, p4est_lib), Cint, (Cint, Cint), ec, o)
end

function p8est_connectivity_edge_neighbor_corner(c, e, ne, o)
    ccall((:p8est_connectivity_edge_neighbor_corner, p4est_lib), Cint, (Cint, Cint, Cint, Cint), c, e, ne, o)
end

function p8est_connectivity_new(num_vertices, num_trees, num_edges, num_ett, num_corners, num_ctt)
    ccall((:p8est_connectivity_new, p4est_lib), Ptr{p8est_connectivity_t}, (p4est_topidx_t, p4est_topidx_t, p4est_topidx_t, p4est_topidx_t, p4est_topidx_t, p4est_topidx_t), num_vertices, num_trees, num_edges, num_ett, num_corners, num_ctt)
end

function p8est_connectivity_new_copy(num_vertices, num_trees, num_edges, num_corners, vertices, ttv, ttt, ttf, tte, eoff, ett, ete, ttc, coff, ctt, ctc)
    ccall((:p8est_connectivity_new_copy, p4est_lib), Ptr{p8est_connectivity_t}, (p4est_topidx_t, p4est_topidx_t, p4est_topidx_t, p4est_topidx_t, Ptr{Cdouble}, Ptr{p4est_topidx_t}, Ptr{p4est_topidx_t}, Ptr{Int8}, Ptr{p4est_topidx_t}, Ptr{p4est_topidx_t}, Ptr{p4est_topidx_t}, Ptr{Int8}, Ptr{p4est_topidx_t}, Ptr{p4est_topidx_t}, Ptr{p4est_topidx_t}, Ptr{Int8}), num_vertices, num_trees, num_edges, num_corners, vertices, ttv, ttt, ttf, tte, eoff, ett, ete, ttc, coff, ctt, ctc)
end

function p8est_connectivity_bcast(conn_in, root, comm)
    ccall((:p8est_connectivity_bcast, p4est_lib), Ptr{p8est_connectivity_t}, (Ptr{p8est_connectivity_t}, Cint, MPI_Comm), conn_in, root, comm)
end

function p8est_connectivity_destroy(connectivity)
    ccall((:p8est_connectivity_destroy, p4est_lib), Cvoid, (Ptr{p8est_connectivity_t},), connectivity)
end

function p8est_connectivity_set_attr(conn, bytes_per_tree)
    ccall((:p8est_connectivity_set_attr, p4est_lib), Cvoid, (Ptr{p8est_connectivity_t}, Csize_t), conn, bytes_per_tree)
end

function p8est_connectivity_is_valid(connectivity)
    ccall((:p8est_connectivity_is_valid, p4est_lib), Cint, (Ptr{p8est_connectivity_t},), connectivity)
end

function p8est_connectivity_is_equal(conn1, conn2)
    ccall((:p8est_connectivity_is_equal, p4est_lib), Cint, (Ptr{p8est_connectivity_t}, Ptr{p8est_connectivity_t}), conn1, conn2)
end

function p8est_connectivity_sink(conn, sink)
    ccall((:p8est_connectivity_sink, p4est_lib), Cint, (Ptr{p8est_connectivity_t}, Ptr{sc_io_sink_t}), conn, sink)
end

function p8est_connectivity_deflate(conn, code)
    ccall((:p8est_connectivity_deflate, p4est_lib), Ptr{sc_array_t}, (Ptr{p8est_connectivity_t}, p8est_connectivity_encode_t), conn, code)
end

function p8est_connectivity_save(filename, connectivity)
    ccall((:p8est_connectivity_save, p4est_lib), Cint, (Cstring, Ptr{p8est_connectivity_t}), filename, connectivity)
end

function p8est_connectivity_source(source)
    ccall((:p8est_connectivity_source, p4est_lib), Ptr{p8est_connectivity_t}, (Ptr{sc_io_source_t},), source)
end

function p8est_connectivity_inflate(buffer)
    ccall((:p8est_connectivity_inflate, p4est_lib), Ptr{p8est_connectivity_t}, (Ptr{sc_array_t},), buffer)
end

function p8est_connectivity_load(filename, bytes)
    ccall((:p8est_connectivity_load, p4est_lib), Ptr{p8est_connectivity_t}, (Cstring, Ptr{Csize_t}), filename, bytes)
end

function p8est_connectivity_new_unitcube()
    ccall((:p8est_connectivity_new_unitcube, p4est_lib), Ptr{p8est_connectivity_t}, ())
end

function p8est_connectivity_new_periodic()
    ccall((:p8est_connectivity_new_periodic, p4est_lib), Ptr{p8est_connectivity_t}, ())
end

function p8est_connectivity_new_rotwrap()
    ccall((:p8est_connectivity_new_rotwrap, p4est_lib), Ptr{p8est_connectivity_t}, ())
end

function p8est_connectivity_new_twocubes()
    ccall((:p8est_connectivity_new_twocubes, p4est_lib), Ptr{p8est_connectivity_t}, ())
end

function p8est_connectivity_new_twotrees(l_face, r_face, orientation)
    ccall((:p8est_connectivity_new_twotrees, p4est_lib), Ptr{p8est_connectivity_t}, (Cint, Cint, Cint), l_face, r_face, orientation)
end

function p8est_connectivity_new_twowrap()
    ccall((:p8est_connectivity_new_twowrap, p4est_lib), Ptr{p8est_connectivity_t}, ())
end

function p8est_connectivity_new_rotcubes()
    ccall((:p8est_connectivity_new_rotcubes, p4est_lib), Ptr{p8est_connectivity_t}, ())
end

function p8est_connectivity_new_brick(m, n, p, periodic_a, periodic_b, periodic_c)
    ccall((:p8est_connectivity_new_brick, p4est_lib), Ptr{p8est_connectivity_t}, (Cint, Cint, Cint, Cint, Cint, Cint), m, n, p, periodic_a, periodic_b, periodic_c)
end

function p8est_connectivity_new_shell()
    ccall((:p8est_connectivity_new_shell, p4est_lib), Ptr{p8est_connectivity_t}, ())
end

function p8est_connectivity_new_sphere()
    ccall((:p8est_connectivity_new_sphere, p4est_lib), Ptr{p8est_connectivity_t}, ())
end

function p8est_connectivity_new_byname(name)
    ccall((:p8est_connectivity_new_byname, p4est_lib), Ptr{p8est_connectivity_t}, (Cstring,), name)
end

function p8est_connectivity_refine(conn, num_per_edge)
    ccall((:p8est_connectivity_refine, p4est_lib), Ptr{p8est_connectivity_t}, (Ptr{p8est_connectivity_t}, Cint), conn, num_per_edge)
end

function p8est_expand_face_transform(iface, nface, ftransform)
    ccall((:p8est_expand_face_transform, p4est_lib), Cvoid, (Cint, Cint, Ptr{Cint}), iface, nface, ftransform)
end

function p8est_find_face_transform(connectivity, itree, iface, ftransform)
    ccall((:p8est_find_face_transform, p4est_lib), p4est_topidx_t, (Ptr{p8est_connectivity_t}, p4est_topidx_t, Cint, Ptr{Cint}), connectivity, itree, iface, ftransform)
end

function p8est_find_edge_transform(connectivity, itree, iedge, ei)
    ccall((:p8est_find_edge_transform, p4est_lib), Cvoid, (Ptr{p8est_connectivity_t}, p4est_topidx_t, Cint, Ptr{p8est_edge_info_t}), connectivity, itree, iedge, ei)
end

function p8est_find_corner_transform(connectivity, itree, icorner, ci)
    ccall((:p8est_find_corner_transform, p4est_lib), Cvoid, (Ptr{p8est_connectivity_t}, p4est_topidx_t, Cint, Ptr{p8est_corner_info_t}), connectivity, itree, icorner, ci)
end

function p8est_connectivity_complete(conn)
    ccall((:p8est_connectivity_complete, p4est_lib), Cvoid, (Ptr{p8est_connectivity_t},), conn)
end

function p8est_connectivity_reduce(conn)
    ccall((:p8est_connectivity_reduce, p4est_lib), Cvoid, (Ptr{p8est_connectivity_t},), conn)
end

function p8est_connectivity_permute(conn, perm, is_current_to_new)
    ccall((:p8est_connectivity_permute, p4est_lib), Cvoid, (Ptr{p8est_connectivity_t}, Ptr{sc_array_t}, Cint), conn, perm, is_current_to_new)
end

function p8est_connectivity_join_faces(conn, tree_left, tree_right, face_left, face_right, orientation)
    ccall((:p8est_connectivity_join_faces, p4est_lib), Cvoid, (Ptr{p8est_connectivity_t}, p4est_topidx_t, p4est_topidx_t, Cint, Cint, Cint), conn, tree_left, tree_right, face_left, face_right, orientation)
end

function p8est_connectivity_is_equivalent(conn1, conn2)
    ccall((:p8est_connectivity_is_equivalent, p4est_lib), Cint, (Ptr{p8est_connectivity_t}, Ptr{p8est_connectivity_t}), conn1, conn2)
end

function p8est_connectivity_read_inp_stream(stream, num_vertices, num_trees, vertices, tree_to_vertex)
    ccall((:p8est_connectivity_read_inp_stream, p4est_lib), Cint, (Ptr{FILE}, Ptr{p4est_topidx_t}, Ptr{p4est_topidx_t}, Ptr{Cdouble}, Ptr{p4est_topidx_t}), stream, num_vertices, num_trees, vertices, tree_to_vertex)
end

function p8est_connectivity_read_inp(filename)
    ccall((:p8est_connectivity_read_inp, p4est_lib), Ptr{p8est_connectivity_t}, (Cstring,), filename)
end
# Julia wrapper for header: p8est_extended.h
# Automatically generated using Clang.jl

function p8est_new_ext(mpicomm, connectivity, min_quadrants, min_level, fill_uniform, data_size, init_fn, user_pointer)
    ccall((:p8est_new_ext, p4est_lib), Ptr{p8est_t}, (MPI_Comm, Ptr{p8est_connectivity_t}, p4est_locidx_t, Cint, Cint, Csize_t, p8est_init_t, Ptr{Cvoid}), mpicomm, connectivity, min_quadrants, min_level, fill_uniform, data_size, init_fn, user_pointer)
end

function p8est_mesh_new_ext(p4est, ghost, compute_tree_index, compute_level_lists, btype)
    ccall((:p8est_mesh_new_ext, p4est_lib), Ptr{p8est_mesh_t}, (Ptr{p8est_t}, Ptr{p8est_ghost_t}, Cint, Cint, p8est_connect_type_t), p4est, ghost, compute_tree_index, compute_level_lists, btype)
end

function p8est_copy_ext(input, copy_data, duplicate_mpicomm)
    ccall((:p8est_copy_ext, p4est_lib), Ptr{p8est_t}, (Ptr{p8est_t}, Cint, Cint), input, copy_data, duplicate_mpicomm)
end

function p8est_refine_ext(p8est, refine_recursive, maxlevel, refine_fn, init_fn, replace_fn)
    ccall((:p8est_refine_ext, p4est_lib), Cvoid, (Ptr{p8est_t}, Cint, Cint, p8est_refine_t, p8est_init_t, p8est_replace_t), p8est, refine_recursive, maxlevel, refine_fn, init_fn, replace_fn)
end

function p8est_coarsen_ext(p8est, coarsen_recursive, callback_orphans, coarsen_fn, init_fn, replace_fn)
    ccall((:p8est_coarsen_ext, p4est_lib), Cvoid, (Ptr{p8est_t}, Cint, Cint, p8est_coarsen_t, p8est_init_t, p8est_replace_t), p8est, coarsen_recursive, callback_orphans, coarsen_fn, init_fn, replace_fn)
end

function p8est_balance_ext(p8est, btype, init_fn, replace_fn)
    ccall((:p8est_balance_ext, p4est_lib), Cvoid, (Ptr{p8est_t}, p8est_connect_type_t, p8est_init_t, p8est_replace_t), p8est, btype, init_fn, replace_fn)
end

function p8est_balance_subtree_ext(p8est, btype, which_tree, init_fn, replace_fn)
    ccall((:p8est_balance_subtree_ext, p4est_lib), Cvoid, (Ptr{p8est_t}, p8est_connect_type_t, p4est_topidx_t, p8est_init_t, p8est_replace_t), p8est, btype, which_tree, init_fn, replace_fn)
end

function p8est_partition_ext(p8est, partition_for_coarsening, weight_fn)
    ccall((:p8est_partition_ext, p4est_lib), p4est_gloidx_t, (Ptr{p8est_t}, Cint, p8est_weight_t), p8est, partition_for_coarsening, weight_fn)
end

function p8est_partition_for_coarsening(p8est, num_quadrants_in_proc)
    ccall((:p8est_partition_for_coarsening, p4est_lib), p4est_gloidx_t, (Ptr{p8est_t}, Ptr{p4est_locidx_t}), p8est, num_quadrants_in_proc)
end

function p8est_iterate_ext(p8est, ghost_layer, user_data, iter_volume, iter_face, iter_edge, iter_corner, remote)
    ccall((:p8est_iterate_ext, p4est_lib), Cvoid, (Ptr{p8est_t}, Ptr{p8est_ghost_t}, Ptr{Cvoid}, p8est_iter_volume_t, p8est_iter_face_t, p8est_iter_edge_t, p8est_iter_corner_t, Cint), p8est, ghost_layer, user_data, iter_volume, iter_face, iter_edge, iter_corner, remote)
end

function p8est_save_ext(filename, p8est, save_data, save_partition)
    ccall((:p8est_save_ext, p4est_lib), Cvoid, (Cstring, Ptr{p8est_t}, Cint, Cint), filename, p8est, save_data, save_partition)
end

function p8est_load_ext(filename, mpicomm, data_size, load_data, autopartition, broadcasthead, user_pointer, connectivity)
    ccall((:p8est_load_ext, p4est_lib), Ptr{p8est_t}, (Cstring, MPI_Comm, Csize_t, Cint, Cint, Cint, Ptr{Cvoid}, Ptr{Ptr{p8est_connectivity_t}}), filename, mpicomm, data_size, load_data, autopartition, broadcasthead, user_pointer, connectivity)
end

function p8est_source_ext(src, mpicomm, data_size, load_data, autopartition, broadcasthead, user_pointer, connectivity)
    ccall((:p8est_source_ext, p4est_lib), Ptr{p8est_t}, (Ptr{sc_io_source_t}, MPI_Comm, Csize_t, Cint, Cint, Cint, Ptr{Cvoid}, Ptr{Ptr{p8est_connectivity_t}}), src, mpicomm, data_size, load_data, autopartition, broadcasthead, user_pointer, connectivity)
end

function p8est_get_plex_data_ext(p8est, ghost, lnodes, ctype, overlap, first_local_quad, out_points_per_dim, out_cone_sizes, out_cones, out_cone_orientations, out_vertex_coords, out_children, out_parents, out_childids, out_leaves, out_remotes, custom_numbering)
    ccall((:p8est_get_plex_data_ext, p4est_lib), Cvoid, (Ptr{p8est_t}, Ptr{Ptr{p8est_ghost_t}}, Ptr{Ptr{p8est_lnodes_t}}, p8est_connect_type_t, Cint, Ptr{p4est_locidx_t}, Ptr{sc_array_t}, Ptr{sc_array_t}, Ptr{sc_array_t}, Ptr{sc_array_t}, Ptr{sc_array_t}, Ptr{sc_array_t}, Ptr{sc_array_t}, Ptr{sc_array_t}, Ptr{sc_array_t}, Ptr{sc_array_t}, Cint), p8est, ghost, lnodes, ctype, overlap, first_local_quad, out_points_per_dim, out_cone_sizes, out_cones, out_cone_orientations, out_vertex_coords, out_children, out_parents, out_childids, out_leaves, out_remotes, custom_numbering)
end
# Julia wrapper for header: p8est_geometry.h
# Automatically generated using Clang.jl

function p8est_geometry_destroy(geom)
    ccall((:p8est_geometry_destroy, p4est_lib), Cvoid, (Ptr{p8est_geometry_t},), geom)
end

function p8est_geometry_new_connectivity(conn)
    ccall((:p8est_geometry_new_connectivity, p4est_lib), Ptr{p8est_geometry_t}, (Ptr{p8est_connectivity_t},), conn)
end

function p8est_geometry_new_shell(conn, R2, R1)
    ccall((:p8est_geometry_new_shell, p4est_lib), Ptr{p8est_geometry_t}, (Ptr{p8est_connectivity_t}, Cdouble, Cdouble), conn, R2, R1)
end

function p8est_geometry_new_sphere(conn, R2, R1, R0)
    ccall((:p8est_geometry_new_sphere, p4est_lib), Ptr{p8est_geometry_t}, (Ptr{p8est_connectivity_t}, Cdouble, Cdouble, Cdouble), conn, R2, R1, R0)
end
# Julia wrapper for header: p8est_ghost.h
# Automatically generated using Clang.jl

function p8est_ghost_is_valid(p8est, ghost)
    ccall((:p8est_ghost_is_valid, p4est_lib), Cint, (Ptr{p8est_t}, Ptr{p8est_ghost_t}), p8est, ghost)
end

function p8est_ghost_memory_used()
    ccall((:p8est_ghost_memory_used, p4est_lib), Cint, ())
end

function p8est_quadrant_find_owner(p8est, treeid, face, q)
    ccall((:p8est_quadrant_find_owner, p4est_lib), Cint, (Ptr{p8est_t}, p4est_topidx_t, Cint, Ptr{p8est_quadrant_t}), p8est, treeid, face, q)
end

function p8est_ghost_new(p8est, btype)
    ccall((:p8est_ghost_new, p4est_lib), Ptr{p8est_ghost_t}, (Ptr{p8est_t}, p8est_connect_type_t), p8est, btype)
end

function p8est_ghost_destroy(ghost)
    ccall((:p8est_ghost_destroy, p4est_lib), Cvoid, (Ptr{p8est_ghost_t},), ghost)
end

function p8est_ghost_bsearch(ghost, which_proc, which_tree, q)
    ccall((:p8est_ghost_bsearch, p4est_lib), ssize_t, (Ptr{p8est_ghost_t}, Cint, p4est_topidx_t, Ptr{p8est_quadrant_t}), ghost, which_proc, which_tree, q)
end

function p8est_ghost_tree_contains(ghost, which_proc, which_tree, q)
    ccall((:p8est_ghost_tree_contains, p4est_lib), ssize_t, (Ptr{p8est_ghost_t}, Cint, p4est_topidx_t, Ptr{p8est_quadrant_t}), ghost, which_proc, which_tree, q)
end

function p8est_face_quadrant_exists(p8est, ghost, treeid, q, face, hang, owner_rank)
    ccall((:p8est_face_quadrant_exists, p4est_lib), p4est_locidx_t, (Ptr{p8est_t}, Ptr{p8est_ghost_t}, p4est_topidx_t, Ptr{p8est_quadrant_t}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}), p8est, ghost, treeid, q, face, hang, owner_rank)
end

function p8est_quadrant_exists(p8est, ghost, treeid, q, exists_arr, rproc_arr, rquad_arr)
    ccall((:p8est_quadrant_exists, p4est_lib), Cint, (Ptr{p8est_t}, Ptr{p8est_ghost_t}, p4est_topidx_t, Ptr{p8est_quadrant_t}, Ptr{sc_array_t}, Ptr{sc_array_t}, Ptr{sc_array_t}), p8est, ghost, treeid, q, exists_arr, rproc_arr, rquad_arr)
end

function p8est_is_balanced(p8est, btype)
    ccall((:p8est_is_balanced, p4est_lib), Cint, (Ptr{p8est_t}, p8est_connect_type_t), p8est, btype)
end

function p8est_ghost_checksum(p8est, ghost)
    ccall((:p8est_ghost_checksum, p4est_lib), UInt32, (Ptr{p8est_t}, Ptr{p8est_ghost_t}), p8est, ghost)
end

function p8est_ghost_exchange_data(p4est, ghost, ghost_data)
    ccall((:p8est_ghost_exchange_data, p4est_lib), Cvoid, (Ptr{p8est_t}, Ptr{p8est_ghost_t}, Ptr{Cvoid}), p4est, ghost, ghost_data)
end

function p8est_ghost_exchange_data_begin(p4est, ghost, ghost_data)
    ccall((:p8est_ghost_exchange_data_begin, p4est_lib), Ptr{p8est_ghost_exchange_t}, (Ptr{p8est_t}, Ptr{p8est_ghost_t}, Ptr{Cvoid}), p4est, ghost, ghost_data)
end

function p8est_ghost_exchange_data_end(exc)
    ccall((:p8est_ghost_exchange_data_end, p4est_lib), Cvoid, (Ptr{p8est_ghost_exchange_t},), exc)
end

function p8est_ghost_exchange_custom(p4est, ghost, data_size, mirror_data, ghost_data)
    ccall((:p8est_ghost_exchange_custom, p4est_lib), Cvoid, (Ptr{p8est_t}, Ptr{p8est_ghost_t}, Csize_t, Ptr{Ptr{Cvoid}}, Ptr{Cvoid}), p4est, ghost, data_size, mirror_data, ghost_data)
end

function p8est_ghost_exchange_custom_begin(p4est, ghost, data_size, mirror_data, ghost_data)
    ccall((:p8est_ghost_exchange_custom_begin, p4est_lib), Ptr{p8est_ghost_exchange_t}, (Ptr{p8est_t}, Ptr{p8est_ghost_t}, Csize_t, Ptr{Ptr{Cvoid}}, Ptr{Cvoid}), p4est, ghost, data_size, mirror_data, ghost_data)
end

function p8est_ghost_exchange_custom_end(exc)
    ccall((:p8est_ghost_exchange_custom_end, p4est_lib), Cvoid, (Ptr{p8est_ghost_exchange_t},), exc)
end

function p8est_ghost_exchange_custom_levels(p8est, ghost, minlevel, maxlevel, data_size, mirror_data, ghost_data)
    ccall((:p8est_ghost_exchange_custom_levels, p4est_lib), Cvoid, (Ptr{p8est_t}, Ptr{p8est_ghost_t}, Cint, Cint, Csize_t, Ptr{Ptr{Cvoid}}, Ptr{Cvoid}), p8est, ghost, minlevel, maxlevel, data_size, mirror_data, ghost_data)
end

function p8est_ghost_exchange_custom_levels_begin(p4est, ghost, minlevel, maxlevel, data_size, mirror_data, ghost_data)
    ccall((:p8est_ghost_exchange_custom_levels_begin, p4est_lib), Ptr{p8est_ghost_exchange_t}, (Ptr{p8est_t}, Ptr{p8est_ghost_t}, Cint, Cint, Csize_t, Ptr{Ptr{Cvoid}}, Ptr{Cvoid}), p4est, ghost, minlevel, maxlevel, data_size, mirror_data, ghost_data)
end

function p8est_ghost_exchange_custom_levels_end(exc)
    ccall((:p8est_ghost_exchange_custom_levels_end, p4est_lib), Cvoid, (Ptr{p8est_ghost_exchange_t},), exc)
end

function p8est_ghost_expand(p8est, ghost)
    ccall((:p8est_ghost_expand, p4est_lib), Cvoid, (Ptr{p8est_t}, Ptr{p8est_ghost_t}), p8est, ghost)
end
# Julia wrapper for header: p8est_iterate.h
# Automatically generated using Clang.jl

function p8est_iterate(p4est, ghost_layer, user_data, iter_volume, iter_face, iter_edge, iter_corner)
    ccall((:p8est_iterate, p4est_lib), Cvoid, (Ptr{p8est_t}, Ptr{p8est_ghost_t}, Ptr{Cvoid}, p8est_iter_volume_t, p8est_iter_face_t, p8est_iter_edge_t, p8est_iter_corner_t), p4est, ghost_layer, user_data, iter_volume, iter_face, iter_edge, iter_corner)
end
# Julia wrapper for header: p8est_lnodes.h
# Automatically generated using Clang.jl

function p8est_lnodes_new(p8est, ghost_layer, degree)
    ccall((:p8est_lnodes_new, p4est_lib), Ptr{p8est_lnodes_t}, (Ptr{p8est_t}, Ptr{p8est_ghost_t}, Cint), p8est, ghost_layer, degree)
end

function p8est_lnodes_destroy(lnodes)
    ccall((:p8est_lnodes_destroy, p4est_lib), Cvoid, (Ptr{p8est_lnodes_t},), lnodes)
end

function p8est_partition_lnodes(p8est, ghost, degree, partition_for_coarsening)
    ccall((:p8est_partition_lnodes, p4est_lib), Cvoid, (Ptr{p8est_t}, Ptr{p8est_ghost_t}, Cint, Cint), p8est, ghost, degree, partition_for_coarsening)
end

function p8est_partition_lnodes_detailed(p4est, ghost, nodes_per_volume, nodes_per_face, nodes_per_edge, nodes_per_corner, partition_for_coarsening)
    ccall((:p8est_partition_lnodes_detailed, p4est_lib), Cvoid, (Ptr{p8est_t}, Ptr{p8est_ghost_t}, Cint, Cint, Cint, Cint, Cint), p4est, ghost, nodes_per_volume, nodes_per_face, nodes_per_edge, nodes_per_corner, partition_for_coarsening)
end

function p8est_ghost_support_lnodes(p8est, lnodes, ghost)
    ccall((:p8est_ghost_support_lnodes, p4est_lib), Cvoid, (Ptr{p8est_t}, Ptr{p8est_lnodes_t}, Ptr{p8est_ghost_t}), p8est, lnodes, ghost)
end

function p8est_ghost_expand_by_lnodes(p4est, lnodes, ghost)
    ccall((:p8est_ghost_expand_by_lnodes, p4est_lib), Cvoid, (Ptr{p8est_t}, Ptr{p8est_lnodes_t}, Ptr{p8est_ghost_t}), p4est, lnodes, ghost)
end

function p8est_lnodes_share_owned_begin(node_data, lnodes)
    ccall((:p8est_lnodes_share_owned_begin, p4est_lib), Ptr{p8est_lnodes_buffer_t}, (Ptr{sc_array_t}, Ptr{p8est_lnodes_t}), node_data, lnodes)
end

function p8est_lnodes_share_owned_end(buffer)
    ccall((:p8est_lnodes_share_owned_end, p4est_lib), Cvoid, (Ptr{p8est_lnodes_buffer_t},), buffer)
end

function p8est_lnodes_share_owned(node_data, lnodes)
    ccall((:p8est_lnodes_share_owned, p4est_lib), Cvoid, (Ptr{sc_array_t}, Ptr{p8est_lnodes_t}), node_data, lnodes)
end

function p8est_lnodes_share_all_begin(node_data, lnodes)
    ccall((:p8est_lnodes_share_all_begin, p4est_lib), Ptr{p8est_lnodes_buffer_t}, (Ptr{sc_array_t}, Ptr{p8est_lnodes_t}), node_data, lnodes)
end

function p8est_lnodes_share_all_end(buffer)
    ccall((:p8est_lnodes_share_all_end, p4est_lib), Cvoid, (Ptr{p8est_lnodes_buffer_t},), buffer)
end

function p8est_lnodes_share_all(node_data, lnodes)
    ccall((:p8est_lnodes_share_all, p4est_lib), Ptr{p8est_lnodes_buffer_t}, (Ptr{sc_array_t}, Ptr{p8est_lnodes_t}), node_data, lnodes)
end

function p8est_lnodes_buffer_destroy(buffer)
    ccall((:p8est_lnodes_buffer_destroy, p4est_lib), Cvoid, (Ptr{p8est_lnodes_buffer_t},), buffer)
end
# Julia wrapper for header: p8est_mesh.h
# Automatically generated using Clang.jl

function p8est_mesh_memory_used()
    ccall((:p8est_mesh_memory_used, p4est_lib), Cint, ())
end

function p8est_mesh_new(p8est, ghost, btype)
    ccall((:p8est_mesh_new, p4est_lib), Ptr{p8est_mesh_t}, (Ptr{p8est_t}, Ptr{p8est_ghost_t}, p8est_connect_type_t), p8est, ghost, btype)
end

function p8est_mesh_destroy(mesh)
    ccall((:p8est_mesh_destroy, p4est_lib), Cvoid, (Ptr{p8est_mesh_t},), mesh)
end

function p8est_mesh_quadrant_cumulative(p8est, cumulative_id, which_tree, quadrant_id)
    ccall((:p8est_mesh_quadrant_cumulative, p4est_lib), Ptr{p8est_quadrant_t}, (Ptr{p8est_t}, p4est_locidx_t, Ptr{p4est_topidx_t}, Ptr{p4est_locidx_t}), p8est, cumulative_id, which_tree, quadrant_id)
end

function p8est_mesh_face_neighbor_init2(mfn, p8est, ghost, mesh, which_tree, quadrant_id)
    ccall((:p8est_mesh_face_neighbor_init2, p4est_lib), Cvoid, (Ptr{p8est_mesh_face_neighbor_t}, Ptr{p8est_t}, Ptr{p8est_ghost_t}, Ptr{p8est_mesh_t}, p4est_topidx_t, p4est_locidx_t), mfn, p8est, ghost, mesh, which_tree, quadrant_id)
end

function p8est_mesh_face_neighbor_init(mfn, p8est, ghost, mesh, which_tree, quadrant)
    ccall((:p8est_mesh_face_neighbor_init, p4est_lib), Cvoid, (Ptr{p8est_mesh_face_neighbor_t}, Ptr{p8est_t}, Ptr{p8est_ghost_t}, Ptr{p8est_mesh_t}, p4est_topidx_t, Ptr{p8est_quadrant_t}), mfn, p8est, ghost, mesh, which_tree, quadrant)
end

function p8est_mesh_face_neighbor_next(mfn, ntree, nquad, nface, nrank)
    ccall((:p8est_mesh_face_neighbor_next, p4est_lib), Ptr{p8est_quadrant_t}, (Ptr{p8est_mesh_face_neighbor_t}, Ptr{p4est_topidx_t}, Ptr{p4est_locidx_t}, Ptr{Cint}, Ptr{Cint}), mfn, ntree, nquad, nface, nrank)
end

function p8est_mesh_face_neighbor_data(mfn, ghost_data)
    ccall((:p8est_mesh_face_neighbor_data, p4est_lib), Ptr{Cvoid}, (Ptr{p8est_mesh_face_neighbor_t}, Ptr{Cvoid}), mfn, ghost_data)
end
# Julia wrapper for header: p8est_search.h
# Automatically generated using Clang.jl

function p8est_find_lower_bound(array, q, guess)
    ccall((:p8est_find_lower_bound, p4est_lib), ssize_t, (Ptr{sc_array_t}, Ptr{p8est_quadrant_t}, Csize_t), array, q, guess)
end

function p8est_find_higher_bound(array, q, guess)
    ccall((:p8est_find_higher_bound, p4est_lib), ssize_t, (Ptr{sc_array_t}, Ptr{p8est_quadrant_t}, Csize_t), array, q, guess)
end

function p8est_split_array(array, level, indices)
    ccall((:p8est_split_array, p4est_lib), Cvoid, (Ptr{sc_array_t}, Cint, Cint), array, level, indices)
end

function p8est_find_range_boundaries(lq, uq, level, faces, edges, corners)
    ccall((:p8est_find_range_boundaries, p4est_lib), Int32, (Ptr{p8est_quadrant_t}, Ptr{p8est_quadrant_t}, Cint, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}), lq, uq, level, faces, edges, corners)
end

function p8est_search_local(p4est, call_post, quadrant_fn, point_fn, points)
    ccall((:p8est_search_local, p4est_lib), Cvoid, (Ptr{p8est_t}, Cint, p8est_search_local_t, p8est_search_local_t, Ptr{sc_array_t}), p4est, call_post, quadrant_fn, point_fn, points)
end

function p8est_search(p4est, quadrant_fn, point_fn, points)
    ccall((:p8est_search, p4est_lib), Cvoid, (Ptr{p8est_t}, p8est_search_query_t, p8est_search_query_t, Ptr{sc_array_t}), p4est, quadrant_fn, point_fn, points)
end

function p8est_search_partition(p4est, call_post, quadrant_fn, point_fn, points)
    ccall((:p8est_search_partition, p4est_lib), Cvoid, (Ptr{p8est_t}, Cint, p8est_search_partition_t, p8est_search_partition_t, Ptr{sc_array_t}), p4est, call_post, quadrant_fn, point_fn, points)
end

function p8est_search_all(p4est, call_post, quadrant_fn, point_fn, points)
    ccall((:p8est_search_all, p4est_lib), Cvoid, (Ptr{p8est_t}, Cint, p8est_search_all_t, p8est_search_all_t, Ptr{sc_array_t}), p4est, call_post, quadrant_fn, point_fn, points)
end
# Julia wrapper for header: p8est_vtk.h
# Automatically generated using Clang.jl

function p8est_vtk_write_file(p8est, geom, filename)
    ccall((:p8est_vtk_write_file, p4est_lib), Cvoid, (Ptr{p8est_t}, Ptr{p8est_geometry_t}, Cstring), p8est, geom, filename)
end

function p8est_vtk_context_new(p4est, filename)
    ccall((:p8est_vtk_context_new, p4est_lib), Ptr{p8est_vtk_context_t}, (Ptr{p8est_t}, Cstring), p4est, filename)
end

function p8est_vtk_context_set_geom(cont, geom)
    ccall((:p8est_vtk_context_set_geom, p4est_lib), Cvoid, (Ptr{p8est_vtk_context_t}, Ptr{p8est_geometry_t}), cont, geom)
end

function p8est_vtk_context_set_scale(cont, scale)
    ccall((:p8est_vtk_context_set_scale, p4est_lib), Cvoid, (Ptr{p8est_vtk_context_t}, Cdouble), cont, scale)
end

function p8est_vtk_context_set_continuous(cont, continuous)
    ccall((:p8est_vtk_context_set_continuous, p4est_lib), Cvoid, (Ptr{p8est_vtk_context_t}, Cint), cont, continuous)
end

function p8est_vtk_context_destroy(context)
    ccall((:p8est_vtk_context_destroy, p4est_lib), Cvoid, (Ptr{p8est_vtk_context_t},), context)
end

function p8est_vtk_write_header(cont)
    ccall((:p8est_vtk_write_header, p4est_lib), Ptr{p8est_vtk_context_t}, (Ptr{p8est_vtk_context_t},), cont)
end

function p8est_vtk_write_footer(cont)
    ccall((:p8est_vtk_write_footer, p4est_lib), Cint, (Ptr{p8est_vtk_context_t},), cont)
end

# Julia wrapper for header: p8est_io.h
# Generated manually
function p8est_deflate_quadrants(p4est, data)
  ccall((:p8est_deflate_quadrants, p4est_lib),
        Ptr{sc_array_t}, (Ptr{p8est_t}, Ptr{Ptr{sc_array_t}}), p4est, data)
end

function p8est_inflate(mpicomm, connectivity,
                       global_first_quadrant, pertree,
                       quadrants, data, user_pointer)

  ccall((:p8est_inflate, p4est_lib),
        Ptr{p8est_t},
        (MPI_Comm, Ptr{p8est_connectivity_t},
         Ptr{p4est_gloidx_t}, Ptr{p4est_gloidx_t},
         Ptr{sc_array_t}, Ptr{sc_array_t}, Ptr{Cvoid}),
        mpicomm, connectivity, global_first_quadrant, pertree, quadrants, data, user_pointer)
end

# Julia wrapper for header: p8est_communication.h
# Generated manually
# void p4est_comm_count_pertree (p4est_t * p4est,
#                                p4est_gloidx_t * pertree)
function p8est_comm_count_pertree(p4est, pertree)
  ccall((:p8est_comm_count_pertree, p4est_lib),
        Cvoid,
        (Ptr{p8est_t}, Ptr{p4est_gloidx_t}),
        p4est, pertree)
end

function p8est_comm_find_owner(p4est, which_tree, q, guess)
  ccall((:p8est_comm_find_owner, p4est_lib),
        Cint,
        (Ptr{p8est_t}, p4est_locidx_t, Ptr{p8est_quadrant_t}, Cint),
        p4est, which_tree, q, guess)
end


text:
module Higher

using ..Omega: RandVar, ciid, randtuple, cond, ==ᵣ, ==ₛ
using DocStringExtensions

include("rcd.jl")          # Random Conditional Distribution
include("rid.jl")          # Random Interventional Distribution

export rid, rcd, ∥, ∥ₛ

end


text:
using Random
function drawball(timer)
    global r, c, d
    print("\e[$r;$(c)H ")       # clear last ball position (r,c)
    if (r+=1) > 14
        close(timer)
        b = (bin[(c+2)>>2] += 1)# update count in bin
        print("\e[$b;$(c)Ho")   # lengthen bar of balls in bin
    else
        r in 3:2:13 && c in 17-r:4:11+r && (d = 2bitrand()-1)
        print("\e[$r;$(c+=d)Ho")# show ball moving in direction d
    end
end

print("\e[2J")                  # clear screen
for r = 3:2:13, c = 17-r:4:11+r # 6 pins in 6 rows
    print("\e[$r;$(c)H^")       # draw pins
end
print("\e[15;2H-------------------------")

bin = fill(15,7)                # positions of top of bins
while "x" != readline() >= ""   # x-Enter: exit, {keys..}Enter: next ball
    global r,c,d = 0,14,0
    t = Timer(drawball, 0, interval=0.1)
    while r < 15 sleep(0.01) end
    print("\e[40;1H")           # move cursor far down
end

max_stars_repo_name: ethansaxenian/RosettaDecode

max_issues_repo_name: ethansaxenian/RosettaDecode

max_forks_repo_name: ethansaxenian/RosettaDecode


text:
using DashBootstrapComponents

email_input = dbc_formgroup(
    [
        dbc_label("Email", html_for="example-email-row", width=2),
        dbc_col(
            dbc_input(
                type="email",
                id="example-email-row",
                placeholder="Enter email",
            ),
            width=10,
        ),
    ],
    row=true,
);

password_input = dbc_formgroup(
    [
        dbc_label("Password", html_for="example-password-row", width=2),
        dbc_col(
            dbc_input(
                type="password",
                id="example-password-row",
                placeholder="Enter password",
            ),
            width=10,
        ),
    ],
    row=true,
);

radios_input = dbc_formgroup(
    [
        dbc_label("Radios", html_for="example-radios-row", width=2),
        dbc_col(
            dbc_radioitems(
                id="example-radios-row",
                options=[
                    Dict("label" => "First radio", "value" => 1),
                    Dict("label" => "Second radio", "value" => 2),
                    Dict(
                        "label" => "Third disabled radio",
                        "value" => 3,
                        "disabled" => true,
                    ),
                ],
            ),
            width=10,
        ),
    ],
    row=true,
);

form = dbc_form([email_input, password_input, radios_input]);

max_stars_repo_name: harisbal/dash-bootstrap-components

max_issues_repo_name: harisbal/dash-bootstrap-components

max_forks_repo_name: harisbal/dash-bootstrap-components


text:
using Weber
using Base.Test
include("find_timing.jl")

function cause_addtrial_error()
  find_timing() do
    addtrial(1)
  end
end

@testset "Moment Type Checks" begin
  @test cause_reserved_error(:bob,:bob) == nothing
end


text:
#!/bin/bash
# -*- mode: julia -*-
#=
exec julia --color=yes --startup-file=no "${BASH_SOURCE[0]}" "$@"
=#
using Test

include("test_parse.jl")
include("test_weights.jl")
include("test_children.jl")
include("test_inorder.jl")
include("test_unionfind.jl")
include("test_root.jl")
include("test_cluster.jl")
include("test_incmat.jl")
include("test_grid.jl")
include("test_incidence.jl")
include("test_lca.jl")
include("test_mst.jl")
include("test_hierarchy.jl")
include("test_stats.jl")
include("test_magick.jl")
include("test_dimacs10.jl")
include("test_snap.jl")

max_stars_repo_name: EQt/graphidx

max_issues_repo_name: EQt/graphidx

max_forks_repo_name: EQt/graphidx


text:
using JSExpr
using Test

include("./jsstring.jl")
include("./ast.jl")
include("./literals.jl")
include("./infix.jl")
include("./interpolation.jl")
include("./call.jl")
include("./macrocall.jl")
include("./function.jl")
include("./jskeywords.jl")
include("./arrays.jl")
include("./objects.jl")
include("./control.jl")
include("./juliaisms.jl")