text:
InputFolder = './Images/CellJunctions/';
OutputFolder = './Results/Images/CellJunctions/';
Fill = -1;
Rescale = 1;

@iA = '*.tif';

@fxg_gRestoreFilam [iA] > [I];
params.FrangiScale = [1.5 2.5];
params.Rmin = 0;
params.Rmax = 13;
params.GaussianVoteRad = 3;
params.ThrVote = [0.05 0.05];
params.NAngles = 24;
params.Delta = [pi/4 pi/8];
params.DScale = [1 0.5];
params.PowerLaw = 0.5;

/endf

/show iA>;
/show I>;
/keep I > tif;

max_stars_repo_name: SebastienTs/LOBSTER

max_issues_repo_name: SebastienTs/LOBSTER

max_forks_repo_name: SebastienTs/LOBSTER


text:
using Oceananigans, Oceananigans.Units, GLMakie

grid = RectilinearGrid(GPU(), size = (256, 256, 256), halo = (3, 3, 3),
                       x = (0, 256), y = (0, 256), z = (-128, 0),
                       topology = (Periodic, Periodic, Bounded))

# Specify coriolis, viscosity / turbulence closure, and boundary condition
coriolis = FPlane(f=1e-4)
closure = AnisotropicMinimumDissipation()
b_bcs = FieldBoundaryConditions(top=FluxBoundaryCondition(1e-8))
boundary_conditions = (; b=b_bcs)

model = NonhydrostaticModel(; grid, coriolis, closure, boundary_conditions,
                              advection = WENO5(), tracers = :b,
                              buoyancy = BuoyancyTracer())

set!(model, b = (x, y, z) -> 1e-6 * z, w = (x, y, z) -> 1e-4 * randn())

# Time-stepping
simulation = Simulation(model, Δt=10, stop_time=1day)

progress(sim) = @info "Iter: $(iteration(sim)), " *
                      "time: $(prettytime(sim)), " *
                      "Δt: $(prettytime(sim.Δt)), " *
                      "wall time: $(prettytime(sim.run_wall_time))"
simulation.callbacks[:progress] = Callback(progress, IterationInterval(100))

wizard = TimeStepWizard(cfl=0.2, max_change=1.1)
simulation.callbacks[:wizard] = Callback(wizard, IterationInterval(100))

times, slices = [], []
function slice_w(sim)
    push!(times, sim.model.clock.time)
    push!(slices, Array(interior(sim.model.velocities.w))[:, 1, :])
    return nothing
end
simulation.callbacks[:slice_catcher] = Callback(slice_w, TimeInterval(5minute))

run!(simulation)

# Visualize vertical velocity
wlim = maximum(abs, model.velocities.w) / 2
x, y, z = nodes(model.velocities.w)
n = Node(1)
fig = Figure(resolution=(800, 600))
title = @lift "Vertical velocity (m s⁻¹) in free convection at t = " * prettytime(times[$n])
ax = Axis(fig[1, 1], title=title, xlabel="x (m)", ylabel="z (m)")
hm = heatmap!(ax, x, z, @lift(slices[$n]), colormap=:balance, colorrange=(-wlim, wlim))
Colorbar(fig[1, 2], hm)

record(fig, "free_convection.mp4", 1:length(times), framerate=12) do nn
    n[] = nn
end

ext: jl


text:
function move_marks(r,side)
    while ismarker(r)==true
        move!(r,side)
    end
end
function reverseside(side)
    side = HorizonSide(mod(Int(side)-1, 4))
end
function putmarks(r,side)
    while isborder(r,side)==false
        move!(r,side)
        putmarker!(r)
    end
end
function tostart(r)
    x=0
    y=0
    while isborder(r,Sud)==0 || isborder(r,West)==0
        if isborder(r,Sud)==0
            move!(r,Sud)
            y+=1
        end
        if isborder(r,West)==0
            move!(r,West)
            x+=1
        end
    end
        return x,y
end
function go_to_west_south_corner_and_return_path!(r::Robot; go_around_barriers::Bool = false, markers = false)::Array{Tuple{HorizonSide,Int64},1}
    my_ans = []
    a = go_to_border_and_return_path!(r, West; go_around_barriers, markers)
    b = go_to_border_and_return_path!(r, Sud
    ; go_around_barriers, markers)

    for i in a
        push!(my_ans, i)
    end
    for i in b
        push!(my_ans, i)
    end
    return my_ans
end
function go_around_barrier_and_return_path!(r::Robot, direct_side::HorizonSide)::Array{Tuple{HorizonSide,Int64},1}
    my_ans = []
    orthogonal_side = clockwise_side(direct_side)
    reverse_side = inverse_side(orthogonal_side)
    num_of_orthohonal_steps = 0
    num_of_direct_steps = 0

    if !isborder(r, direct_side)

        my_ans = [ (Nord, 0) ]
    else
        while isborder(r,direct_side) == true
            if isborder(r, orthogonal_side) == false
                move!(r, orthogonal_side)
                num_of_orthohonal_steps += 1
            else
                break
            end
        end

        if isborder(r,direct_side) == false
            move!(r,direct_side)
            num_of_direct_steps += 1
            while isborder(r,reverse_side) == true
                num_of_direct_steps += 1
                move!(r,direct_side)
            end
            push!(my_ans, (inverse_side(orthogonal_side), num_of_orthohonal_steps) )
            push!(my_ans, (inverse_side(direct_side), num_of_direct_steps) )
            push!(my_ans, (inverse_side(reverse_side), num_of_orthohonal_steps) )
        else
            my_ans = [ (Nord, 0) ]
        end

        while num_of_orthohonal_steps > 0
            num_of_orthohonal_steps=num_of_orthohonal_steps-1
            move!(r,reverse_side)
        end

    end
    return my_ans
end
function get_path_length_in_direction(path::Array{Tuple{HorizonSide,Int64},1}, direction::HorizonSide)::Int
    my_ans = 0
    for i in path
        (i[1] == direction || i[1] == inverse_side(direction)) ? my_ans += i[2] : Nothing
    end
    return my_ans
end
function go_to_border_and_return_path!(r::Robot, side::HorizonSide; go_around_barriers::Bool = false, markers = false)::Array{Tuple{HorizonSide,Int64},1}
    my_ans = [ (Nord, 0) ]
    if go_around_barriers
        steps = 0
        if markers
            putmarker!(r)
        end
        if !isborder(r, side)
            move!(r, side)
            steps = 1
            push!(my_ans, (inverse_side(side), 1) )
        else
            path = go_around_barrier_and_return_path!(r, side)
            steps = get_path_length_in_direction(path, side)
            for i in path
                push!(my_ans, i)
            end
        end
        if markers
            putmarker!(r)
        end
        while steps > 0
            if !isborder(r, side)
                move!(r, side)
                steps = 1
                push!(my_ans, (inverse_side(side), 1) )
                if markers
                    putmarker!(r)
                end
            else
                path = go_around_barrier_and_return_path!(r, side)
                steps = get_path_length_in_direction(path, side)
                for i in path
                    push!(my_ans, i)
                end
                if markers
                    putmarker!(r)
                end
            end
        end

    else
        steps=0
        steps_now = go!(r,side; markers)
        while steps_now > 0
            steps += steps_now
            steps_now = go!(r,side; markers)
        end
        push!(my_ans, (inverse_side(side), steps) )
    end
    return my_ans
end
function find_special!(r::Robot, my_ans::Int, border_now::Bool, side::HorizonSide)
    if isborder(r, side)
        border_now = true
    end
    if !isborder(r, side) && border_now
        border_now = false
        my_ans += 1
    end
    return my_ans, border_now
end
function corner_marking(r::Robot)
    robot_path = []
    while (isborder(r, Sud) == false) | (isborder(r, West) == false)
        push!(robot_path, show_path_after_moving(r, West))
        push!(robot_path, show_path_after_moving(r, Sud))
    end
    for side in (Nord, Ost, Sud, West)
        while isborder(r, side) == false
            move!(r, side)
        end
        putmarker!(r)
    end
    back_by_path(r, robot_path)
end
function back_by_path(r::Robot, path::Array)
    k = length(path)
    n = 1 + (k % 2)
    for i in 1:k
        n = n + 1
        side = Nord
        if n % 2 == 1
            side = Ost
        end
        move_n(r, side, path[k - i + 1])
    end
end
function show_path_after_moving(r::Robot, side::HorizonSide)
    n = 0
    while isborder(r, side)==false
        move!(r, side)
        n = n + 1
    end
    return n
end
function clockwise_side(side)
    return HorizonSide(mod(Int(side)-1,4))
end
function inverse_side(side)
    return HorizonSide(mod(Int(side)+2, 4))
end
function special_move!(r,side,num)
    for _ in 1:num
        if ismarker(r)
            return nothing
        end
        isborder(r, side) ? go_around(r, side) : move!(r,side)
    end
end
function counterclockwise_side(side)
    return HorizonSide(mod(Int(side)+1,4))
end
function go_around(r, direct_side)
    move_side = clockwise_side(direct_side)
    left_moves = 0
    right_moves = 0
    while isborder(r, direct_side)
        left_moves += 1
        right_moves = left_moves
        while isborder(r,direct_side) && right_moves > 0
            right_moves -= 1
            move!(r,move_side)
        end
        side=inverse_side(move_side)
    end
    move!(r,direct_side)
    left_moves /= 2
    while left_moves > 0
        left_moves -= 1
        move!(r,move_side)
    end
end
function direction_mark(r::Robot, side::HorizonSide, n::Int, all::Int)
    k = 0
    p = 0
    while isborder(r, side) == false
        p = 0
        for i in 1:n
            if isborder(r, side) == false
                putmarker!(r)
                move!(r, side)
                k = k + 1
                p += 1
            end
        end
        if (isborder(r, side) == true) && (p != n)
            putmarker!(r)
        end
        for j in 1:n
            if isborder(r, side) == false
                move!(r, side)
                k += 1
            end
        end
    end
    l = 2n + 1
    while all >= l
        if all == l
            move!(r, HorizonSide(mod(Int(side) + 2, 4)))
            if ismarker(r) == false
                move!(r, side)
                putmarker!(r)
            end
        end
        l= l + 3n
    end
    return k
end
function move_n(r::Robot, side::HorizonSide, n::Int)
    for i in 1:n
        move!(r, side)
    end
end
function go_to_bottom_left_corner_return_coords_shift_of_start(r::Robot)
    x=0
    y=0
    while isborder(r, West) == false
        move!(r, West)
        x = x + 1
    end
    while isborder(r, Sud) == false
        move!(r, Sud)
        y = y + 1
    end
    return x, y
end
function show_path_after_moving(r::Robot, side::HorizonSide)
    n = 0
    while isborder(r, side) == false
        move!(r, side)
        n = n + 1
    end
    return n
end
function moveandcheck(r,side)
    fl=true
    while isborder(r,side)==false
        if isborder(r,Nord)==false
            move!(r,side)
        else
            fl=false
            break
        end
    end
    if fl
        move!(r,Nord)
        return moveandcheck(r,reverse(side))
    end
    return side
end
function reverse(side)
    side = HorizonSide(mod(Int(side)+2, 4))
end
function markerBorder(r,side,bside)
    while isborder(r,bside)==true
        putmarker!(r)
        move!(r,side)
    end
    putmarker!(r)
    move!(r,bside)
end
function obojti(r::Robot,side::HorizonSide)
    """Обходит прямоугольные препятствия в направлении side,
     возвращает на сколько изменилась координата робота по оси, соответсвующей side"""
    tmp=0
    m=0
    nside=reverseside(side)
    kside=reverseside(reverseside(nside))
    while isborder(r,side)==true && isborder(r,nside)==false
        move!(r,nside)
        tmp+=1
    end
    if isborder(r,side)==true && isborder(r,nside)==true
        for i in 1:tmp
            move!(r,kside)
        end
    else
        move!(r,side)
        m+=1
        while isborder(r,kside)==true
            move!(r,side)
            m+=1
        end
        for i in 1:tmp
            move!(r,kside)
        end
    end
    return m
end
function movetonord(r,x,y)
    while isborder(r,Nord)==0
        if ((x+y)%2==0)
            putmarker!(r)
        end
        move!(r,Nord)
        y+=1
        if ((x+y)%2==0)
            putmarker!(r)
        end
    end
    return y
end
function movetosud(r,x,y)
    while isborder(r,Sud)==0
        if ((x+y)%2==0)
            putmarker!(r)
        end
        move!(r,Sud)
        y+=1
    end
    return y
end
function moveToSide(r,side)
    k=0
    n=0
    while isborder(r,side)==false
        if ismarker(r)==true
            k+=temperature(r)
            n+=1
        end
        move!(r,side)
    end
    return k,n
end
function move_diog(r,side)
    x=0
    y=0
    while isborder(r,side[1])==false && isborder(r,side[2])==false
        move!(r,side[1])
        move!(r,side[2])
        x+=1
        y+=1
        putmarker!(r)
    end
    return x,y
end
function rtn_diog(r,side,x,y)
    side=(reverse(side[1]),reverse(side[2]))
    for i in 1:x
        move!(r,side[1])
    end
    for i in 1:y
        move!(r,side[2])
    end
end
function todefault(r,side,x)
    while (isborder(r,side)==false)&&x>0
        move!(r,side)
        x-=1
    end
    if x>0
        t=obojti(r,side)
        if t!=0
            x-=t
            todefault(r,side,x)
        else
            return x
        end
    end
end
function movetoside(r,side)
    x=0
    while isborder(r,side)==false
        putmarker!(r)
        move!(r,side)
        x+=1
    end
    putmarker!(r)
    t=obojti(r,side)
    if t!=0
        x+=t
        x+=movetoside(r,side)
    else
        return x
    end
end
function rtn(r,side,x)
    while x>1&&isborder(r,side)==false
        move!(r,side)
        x-=1
    end
    t=obojti(r,side)
    if t!=0&&x>1
        x-=t
        x-=rtn(r,side,x)
    else
        print(x)
        return x
    end
end
function go_to_border_come_back_and_return_distance!(r::Robot, side::HorizonSide; go_around_barriers::Bool = false, markers = false)::Int
    my_ans = 0
    if go_around_barriers
        # здесь и далее интерпритатор понимает, что я хочу записать в именованный параметр markers вызываемой функции значение из параметра markers текущей функции
        if markers
            putmarker!(r)
        end
        if !isborder(r, side)
            move!(r, side)
            steps = 1
        else
            steps = get_path_length_in_direction(go_around_barrier_and_return_path!(r, side), side)
        end
        my_ans += steps
        if markers
            putmarker!(r)
        end
        while steps > 0
            if !isborder(r, side)
                move!(r, side)
                steps = 1
            else
                steps = get_path_length_in_direction(go_around_barrier_and_return_path!(r, side), side)
            end
            my_ans += steps
        end
        if markers
            putmarker!(r)
        end
        go!(r, inverse_side(side); steps = my_ans, go_around_barriers = true)
    else
        while go!(r, side; markers) > 0
            my_ans += 1
        end
        go!(r, inverse_side(side); steps = my_ans)
    end
    return my_ans
end
function go!(r::Robot, side::HorizonSide; steps::Int = 1, go_around_barriers::Bool = false, markers = false)::Int
    my_ans = 0
    if markers
        putmarker!(r)
    end
    if (go_around_barriers)
        path = around_move_return_path!(r, side; steps, markers)
        my_ans = get_path_length_in_direction(path, side)
    else
        for i ∈ 1:steps

            if (markers)
                putmarker!(r)
            end

            if !isborder(r, side)
                move!(r, side)
                my_ans += 1
            else
                for i ∈ 1:my_ans
                    move!(r, inverse_side(side))
                end
                my_ans = 0
                break
            end
        end
        if (markers)
            putmarker!(r)
        end
    end

    return my_ans
end
function around_move_return_path!(r::Robot, side::HorizonSide; steps::Int = 1, markers = false)::Array{Tuple{HorizonSide,Int64},1}
    path = [ (Nord, 0) ]
    steps_to_do = steps

    while steps_to_do > 0

        if markers
            putmarker!(r)
        end

        path_now = go_around_barrier_and_return_path!(r, side)

        for i in path_now
            push!(path, i)
        end

        steps_to_do -= get_path_length_in_direction(path_now, side)

        if !isborder(r, side) && steps_to_do > 0
            push!(path, ( inverse_side(side), 1))
            move!(r, side)
            steps_to_do -= 1

            if markers
                putmarker!(r)
            end
        elseif get_path_length_in_direction(path_now, side) == 0
            steps_to_do = -1
            break
        end
        if markers && steps_to_do >= 0
            putmarker!(r)
        end
    end
    if steps_to_do < 0
        my_ans = 0
        # возвращаемся назад
        go_by_path!(r, path)
        path = [ (North, 0) ]
    end

    return path
end
function go_by_path!(r::Robot, path::Array{Tuple{HorizonSide,Int64},1})
    new_path = reverse(path)
    for i in new_path
        go!(r, i[1]; steps = i[2])
    end
end
function find_special!(r::Robot, my_ans::Int, border_now::Bool, side::HorizonSide)
    if isborder(r, side)
        border_now = true
    end
    if !isborder(r, side) && border_now
        border_now = false
        my_ans += 1
    end
    return my_ans, border_now
end

function move_if_possible!(r::Robot, direct_side::HorizonSide)::Bool
    orthogonal_side = counterclockwise_side(direct_side)
    reverse_side = inverse_side(orthogonal_side)
    num_steps=0
    if isborder(r,direct_side)==false
        move!(r,direct_side)
        result=true
    else
        while isborder(r,direct_side) == true
            if isborder(r, orthogonal_side) == false
                move!(r, orthogonal_side)
                num_steps += 1
            else
                break
            end
        end
        if isborder(r,direct_side) == false
            move!(r,direct_side)
            while isborder(r,reverse_side) == true
                move!(r,direct_side)
            end
            result = true
        else
            result = false
        end
        while num_steps>0
            num_steps=num_steps-1
            move!(r,reverse_side)
        end
    end
    return result
end


text:
## NotANumber

struct NotANumber <: Number end

"""
   Infinity()

represents infinite cardinality. Note that `Infinity <: Integer` to support
being treated as an index.
"""
struct Infinity <: Integer end

const ∞ = Infinity()

show(io::IO, ::Infinity) = print(io, "∞")
string(::Infinity) = "∞"

promote_rule(::Type{Infinity}, ::Type{II}) where II<:Integer = Union{Infinity,II}

convert(::Type{Float64}, ::Infinity) = Inf64
convert(::Type{Float32}, ::Infinity) = Inf32
convert(::Type{Float16}, ::Infinity) = Inf16
convert(::Type{AF}, ::Infinity) where AF<:AbstractFloat = convert(AF, Inf)

sign(y::Infinity) = 1
angle(x::Infinity) = 0

==(x::Infinity, y::Infinity) = true

one(::Type{Infinity}) = 1
zero(::Infinity) = 0

isinf(::Infinity) = true
isfinite(::Infinity) = false

==(x::Infinity, y::Number) = isinf(y) && angle(y) == angle(x)
==(y::Number, x::Infinity) = x == y

isless(x::Infinity, y::Infinity) = false
isless(x::Real, y::Infinity) = isfinite(x) || sign(y) == -1
isless(x::AbstractFloat, y::Infinity) = isless(x, convert(typeof(x), y))
isless(x::Infinity, y::AbstractFloat) = false
isless(x::Infinity, y::Real) = false

+(::Infinity, ::Infinity) = ∞
+(::Number, y::Infinity) = ∞
+(::Infinity, ::Number) = ∞
-(::Infinity, ::Number) = ∞
-(x::Number, ::Infinity) = x + (-∞)

+(::Integer, y::Infinity) = ∞
+(::Infinity, ::Integer) = ∞
-(::Infinity, ::Integer) = ∞
-(x::Integer, ::Infinity) = x + (-∞)
+(::Complex, y::Infinity) = ∞
+(::Infinity, ::Complex) = ∞
-(::Infinity, ::Complex) = ∞
-(x::Complex, ::Infinity) = x + (-∞)

-(::Infinity, ::Infinity) = NotANumber()

# ⊻ is xor
*(::Infinity) = ∞
*(::Infinity, ::Infinity) = ∞

for OP in (:fld,:cld,:div)
  @eval begin
    $OP(::Infinity, ::Real) = ∞
    $OP(::Infinity, ::Infinity) = NotANumber()
  end
end

div(::T, ::Infinity) where T<:Real = zero(T)
fld(x::T, ::Infinity) where T<:Real = signbit(x) ? -one(T) : zero(T)
cld(x::T, ::Infinity) where T<:Real = signbit(x) ? zero(T) : one(T)

mod(::Infinity, ::Infinity) = NotANumber()
mod(::Infinity, ::Real) = NotANumber()
function mod(x::Real, ::Infinity)
    x ≥ 0 || throw(ArgumentError("mod(x,∞) is unbounded for x < 0"))
    x
end

min(::Infinity, ::Infinity) = ∞
max(::Infinity, ::Infinity) = ∞
min(x::Real, ::Infinity) = x
max(::Real, ::Infinity) = ∞
min(::Infinity, x::Real) = x
max(::Infinity, ::Real) = ∞

≤(::Infinity, ::Infinity) = true
<(::Infinity, ::Infinity) = false
≥(::Infinity, ::Infinity) = true
>(::Infinity, ::Infinity) = false

for OP in (:<, :≤)
    @eval begin
        $OP(::Real, ::Infinity) = true
        $OP(::Infinity, ::Real) = false
    end
end

for OP in (:>, :≥)
    @eval begin
        $OP(::Real, ::Infinity) = false
        $OP(::Infinity, ::Real) = true
    end
end

struct SignedInfinity <: Integer
    signbit::Bool
end

SignedInfinity() = SignedInfinity(false)
SignedInfinity(::Infinity) = SignedInfinity()
SignedInfinity(x::SignedInfinity) = x

-(::Infinity) = SignedInfinity(true)
+(::Infinity) = ∞

isinf(::SignedInfinity) = true
isfinite(::SignedInfinity) = false

promote_rule(::Type{Infinity}, ::Type{SignedInfinity}) = SignedInfinity
convert(::Type{SignedInfinity}, ::Infinity) = SignedInfinity(false)

signbit(y::SignedInfinity) = y.signbit
sign(y::SignedInfinity) = 1-2signbit(y)
angle(x::SignedInfinity) = π*signbit(x)
mod(::SignedInfinity, ::SignedInfinity) = NotANumber()
mod(::SignedInfinity, ::Real) = NotANumber()
function mod(x::Real, y::SignedInfinity)
    signbit(x) == signbit(y) || throw(ArgumentError("mod($x,$y) is unbounded"))
    x
end

string(y::SignedInfinity) = signbit(y) ? "-∞" : "+∞"
show(io::IO, y::SignedInfinity) = print(io, string(y))

==(x::SignedInfinity, y::Infinity) = !x.signbit
==(y::Infinity, x::SignedInfinity) = !x.signbit
==(x::SignedInfinity, y::SignedInfinity) = x.signbit == y.signbit

==(x::SignedInfinity, y::Number) = isinf(y) && signbit(y) == signbit(x)
==(y::Number, x::SignedInfinity) = x == y

isless(x::SignedInfinity, y::SignedInfinity) = signbit(x) && !signbit(y)
for Typ in (:Number, :Real, :Integer, :AbstractFloat)
    @eval begin
        isless(x::SignedInfinity, y::$Typ) = signbit(x) && y ≠ -∞
        isless(x::$Typ, y::SignedInfinity) = !signbit(y) && x ≠ ∞
        +(::$Typ, y::SignedInfinity) = y
        +(y::SignedInfinity, ::$Typ) = y
        -(y::SignedInfinity, ::$Typ) = y
        -(::$Typ, y::SignedInfinity) = -y
        function *(a::$Typ, y::SignedInfinity)
            iszero(a) && throw(ArgumentError("Cannot multiply $a * $y"))
            a > 0 ? y : (-y)
        end
    end
end

≤(::SignedInfinity, ::Infinity) = true
≤(::Infinity, s::SignedInfinity) = !signbit(s)
<(s::SignedInfinity, ::Infinity) = signbit(s)
<(::Infinity, ::SignedInfinity) = false
≥(s::SignedInfinity, ::Infinity) = !signbit(s)
≥(::Infinity, ::SignedInfinity) = true
>(::SignedInfinity, ::Infinity) = false
>(::Infinity, s::SignedInfinity) = signbit(s)

function -(::Infinity, y::SignedInfinity)
    signbit(y) || throw(ArgumentError("Cannot subtract ∞ from ∞"))
    ∞
end

function -(x::SignedInfinity, ::Infinity)
    signbit(x) || throw(ArgumentError("Cannot subtract ∞ from ∞"))
    x
end

function -(x::SignedInfinity, y::SignedInfinity)
    signbit(x) == !signbit(y) || throw(ArgumentError("Cannot subtract ∞ from ∞"))
    x
end

-(y::SignedInfinity) = SignedInfinity(!y.signbit)

function +(x::SignedInfinity, y::SignedInfinity)
    x == y || throw(ArgumentError("Angles must be the same to add ∞"))
    x
end

+(x::SignedInfinity, y::Infinity) = x+SignedInfinity(y)
+(x::Infinity, y::SignedInfinity) = SignedInfinity(x)+y

# ⊻ is xor
*(a::SignedInfinity, b::SignedInfinity) = SignedInfinity(signbit(a) ⊻ signbit(b))
*(a::Infinity, b::SignedInfinity) = SignedInfinity(a)*b
*(a::SignedInfinity, b::Infinity) = a*SignedInfinity(b)

*(a::Integer, y::Infinity) = a*SignedInfinity(y)
*(y::Infinity, a::Integer) = SignedInfinity(y)*a

*(a::Real, y::Infinity) = a*SignedInfinity(y)
*(y::Infinity, a::Real) = SignedInfinity(y)*a

*(y::SignedInfinity, a::Real) = a*y
*(y::SignedInfinity, a::Integer) = a*y

<(x::SignedInfinity, y::SignedInfinity) = signbit(x) & !signbit(y)
≤(x::SignedInfinity, y::SignedInfinity) = signbit(x) | !signbit(y)

for OP in (:<,:≤)
    @eval begin
        $OP(x::Real, y::SignedInfinity) = !signbit(y)
        $OP(y::SignedInfinity, x::Real) = signbit(y)
    end
end

min(x::SignedInfinity, y::SignedInfinity) = SignedInfinity(x.signbit | y.signbit)
max(x::SignedInfinity, y::SignedInfinity) = SignedInfinity(x.signbit & y.signbit)
min(x::Real, y::SignedInfinity) = y.signbit ? x : y
max(x::Real, y::SignedInfinity) = y.signbit ? y : x
min(x::SignedInfinity, y::Real) = x.signbit ? x : y
max(x::SignedInfinity, y::Real) = x.signbit ? y : x
min(x::SignedInfinity, ::Infinity) = x
max(::SignedInfinity, ::Infinity) = ∞
min(::Infinity, x::SignedInfinity) = x
max(::Infinity, x::SignedInfinity) = ∞

######
# OrientedInfinity
#######

# angle is π*a where a is (false==0) and (true==1)
struct OrientedInfinity{T<:Real} <: Number
    angle::T
end

OrientedInfinity{T}() where T = OrientedInfinity(zero(T))
OrientedInfinity() = OrientedInfinity{Bool}()
OrientedInfinity{T}(::Infinity) where T<:Real = OrientedInfinity{T}()
OrientedInfinity(::Infinity) = OrientedInfinity()
OrientedInfinity{T}(x::SignedInfinity) where T<:Real = OrientedInfinity{T}(signbit(x))
OrientedInfinity(x::SignedInfinity) = OrientedInfinity(signbit(x))

isinf(::OrientedInfinity) = true
isfinite(::OrientedInfinity) = false

promote_rule(::Type{Infinity}, ::Type{OrientedInfinity{T}}) where T = OrientedInfinity{T}
convert(::Type{OrientedInfinity{T}}, ::Infinity) where T = OrientedInfinity{T}()
convert(::Type{OrientedInfinity}, ::Infinity) = OrientedInfinity()
convert(::Type{OrientedInfinity{T}}, x::SignedInfinity) where T = OrientedInfinity{T}(x)
convert(::Type{OrientedInfinity}, x::SignedInfinity) = OrientedInfinity(x)

sign(y::OrientedInfinity{<:Integer}) = mod(y.angle,2) == 0 ? 1 : -1
angle(x::OrientedInfinity) = π*x.angle
mod(::OrientedInfinity{<:Integer}, ::Integer) = NotANumber()

show(io::IO, x::OrientedInfinity) = print(io, "$(exp(im*π*x.angle))∞")

==(x::OrientedInfinity, y::Infinity) = x.angle == 0
==(y::Infinity, x::OrientedInfinity) = x.angle == 0
==(x::OrientedInfinity, y::SignedInfinity) = x.angle == signbit(y)
==(y::SignedInfinity, x::OrientedInfinity) = x.angle == signbit(y)
==(x::OrientedInfinity, y::OrientedInfinity) = x.angle == y.angle

==(x::OrientedInfinity, y::Number) = isinf(y) && angle(y) == angle(x)
==(y::Number, x::OrientedInfinity) = x == y

isless(x::OrientedInfinity{Bool}, y::OrientedInfinity{Bool}) = x.angle && !y.angle
isless(x::Number, y::OrientedInfinity{Bool}) = !y.angle && x ≠ ∞
isless(x::OrientedInfinity{Bool}, y::Number) = x.angle && y ≠ -∞

-(y::OrientedInfinity{B}) where B<:Integer = sign(y) == 1 ? OrientedInfinity(one(B)) : OrientedInfinity(zero(B))

function +(x::OrientedInfinity, y::OrientedInfinity)
    x == y || throw(ArgumentError("Angles must be the same to add ∞"))
    promote_type(typeof(x),typeof(y))(x.angle)
end

+(x::OrientedInfinity, y::Infinity) = x+OrientedInfinity(y)
+(x::Infinity, y::OrientedInfinity) = OrientedInfinity(x)+y
+(x::OrientedInfinity, y::SignedInfinity) = x+OrientedInfinity(y)
+(x::SignedInfinity, y::OrientedInfinity) = OrientedInfinity(x)+y
+(::Number, y::OrientedInfinity) = y
+(y::OrientedInfinity, ::Number) = y
-(y::OrientedInfinity, ::Number) = y
-(::Number, y::OrientedInfinity) = -y

# ⊻ is xor
*(a::OrientedInfinity{Bool}, b::OrientedInfinity{Bool}) = OrientedInfinity(a.angle ⊻ b.angle)
*(a::OrientedInfinity, b::OrientedInfinity) = OrientedInfinity(a.angle + b.angle)
*(a::Infinity, b::OrientedInfinity) = OrientedInfinity(a)*b
*(a::OrientedInfinity, b::Infinity) = a*OrientedInfinity(b)
*(a::SignedInfinity, b::OrientedInfinity) = OrientedInfinity(a)*b
*(a::OrientedInfinity, b::SignedInfinity) = a*OrientedInfinity(b)

*(a::Real, y::OrientedInfinity) = a > 0 ? y : (-y)
*(y::OrientedInfinity, a::Real) = a*y

*(a::Number, y::OrientedInfinity) = OrientedInfinity(y.angle+angle(a)/π)
*(y::OrientedInfinity, a::Number) = a*y

*(a::Number, y::Infinity) = a*OrientedInfinity(y)
*(y::Infinity, a::Number) = OrientedInfinity(y)*a
*(y::SignedInfinity, a::Number) = OrientedInfinity(y)*a

*(a::Complex, y::Infinity) = a*OrientedInfinity(y)
*(y::Infinity, a::Complex) = OrientedInfinity(y)*a

*(a::Complex,y::SignedInfinity) = a*OrientedInfinity(y)
*(y::SignedInfinity, a::Complex) = OrientedInfinity(y)*a

for OP in (:fld,:cld,:div)
  @eval $OP(y::OrientedInfinity, a::Number) = y*(1/sign(a))
end

min(x::OrientedInfinity{B}, y::OrientedInfinity{B}) where B<:Integer = sign(x) == -1 ? x : y
max(x::OrientedInfinity{B}, ::OrientedInfinity{B}) where B<:Integer = sign(x) == 1 ? x : y
min(x::Real, y::OrientedInfinity{B}) where B<:Integer = sign(y) == 1 ? x : y
min(x::OrientedInfinity{B}, y::Real) where B<:Integer = min(y,x)
max(x::Real, y::OrientedInfinity{B}) where B<:Integer = sign(y) == 1 ? y : x
max(x::OrientedInfinity{B}, y::Real) where B<:Integer = max(y,x)

for OP in (:<,:≤)
    @eval begin
        $OP(x::Real, y::OrientedInfinity{B}) where B<:Integer = sign(y) ==  1
        $OP(y::OrientedInfinity{B}, x::Real) where B<:Integer = sign(y) == -1
    end
end

for OP in (:>, :≥)
    @eval begin
        $OP(x::Real, y::OrientedInfinity{B}) where B<:Integer = sign(y) == -1
        $OP(y::OrientedInfinity{B}, x::Real) where B<:Integer = sign(y) == 1
    end
end

##
# Checked
##

Base.Checked.checked_sub(::Integer, ::Infinity) = -∞
Base.Checked.checked_sub(::Infinity, ::Integer) = ∞
Base.Checked.checked_add(::Integer, ::Infinity) = ∞
Base.Checked.checked_add(::Infinity, ::Integer) = ∞

Base.Checked.checked_sub(::Integer, x::SignedInfinity) = -x
Base.Checked.checked_sub(x::SignedInfinity, ::Integer) = x
Base.Checked.checked_add(::Integer, x::SignedInfinity) = x
Base.Checked.checked_add(x::SignedInfinity, ::Integer) = x

Base.to_index(::Infinity) = ∞


text: println("Hello Stephen, from Julia!")

max_stars_repo_name: srosenthal/hello-worlds

max_issues_repo_name: srosenthal/hello-worlds

max_forks_repo_name: srosenthal/hello-worlds


text:
####################################### BEGIN COMMON #######################################

# Automatically generated using Clang.jl wrap_c, version 0.0.0

# Translated from the libpq headers which are under the following copyright:
### PostgreSQL is Copyright © 1996-2017 by the PostgreSQL Global Development Group.
###
### Postgres95 is Copyright © 1994-5 by the Regents of the University of California.
###
### Permission to use, copy, modify, and distribute this software and its documentation for
### any purpose, without fee, and without a written agreement is hereby granted, provided
### that the above copyright notice and this paragraph and the following two paragraphs
### appear in all copies.
###
### IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT,
### INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
### OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
### CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
###
### THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
### LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
### PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN “AS-IS” BASIS, AND THE UNIVERSITY OF
### CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
### MODIFICATIONS.

using Compat

const OBJC_NEW_PROPERTIES = 1

const NULL = C_NULL
const RENAME_SECLUDE = 0x00000001
const RENAME_SWAP = 0x00000002
const RENAME_EXCL = 0x00000004
const BUFSIZ = 1024
const EOF = -1
const FOPEN_MAX = 20
const FILENAME_MAX = 1024
const P_tmpdir = "/var/tmp/"
const L_tmpnam = 1024
const TMP_MAX = 308915776
const SEEK_SET = 0
const SEEK_CUR = 1
const SEEK_END = 2
const L_ctermid = 1024

# Skipping MacroDefinition: PG_INT64_TYPE long int
# Skipping MacroDefinition: InvalidOid ( ( Oid ) 0 )

const PG_DIAG_SEVERITY = 'S'
const PG_DIAG_SEVERITY_NONLOCALIZED = 'V'
const PG_DIAG_SQLSTATE = 'C'
const PG_DIAG_MESSAGE_PRIMARY = 'M'
const PG_DIAG_MESSAGE_DETAIL = 'D'
const PG_DIAG_MESSAGE_HINT = 'H'
const PG_DIAG_STATEMENT_POSITION = 'P'
const PG_DIAG_INTERNAL_POSITION = 'p'
const PG_DIAG_INTERNAL_QUERY = 'q'
const PG_DIAG_CONTEXT = 'W'
const PG_DIAG_SCHEMA_NAME = 's'
const PG_DIAG_TABLE_NAME = 't'
const PG_DIAG_COLUMN_NAME = 'c'
const PG_DIAG_DATATYPE_NAME = 'd'
const PG_DIAG_CONSTRAINT_NAME = 'n'
const PG_DIAG_SOURCE_FILE = 'F'
const PG_DIAG_SOURCE_LINE = 'L'
const PG_DIAG_SOURCE_FUNCTION = 'R'
const PG_COPYRES_ATTRS = 0x01
const PG_COPYRES_TUPLES = 0x02
const PG_COPYRES_EVENTS = 0x04
const PG_COPYRES_NOTICEHOOKS = 0x08

function PQsetdb(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME)
    PQsetdbLogin(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME, C_NULL, C_NULL)
end
PQfreeNotify(ptr) = PQfreemem(ptr)

const PQnoPasswordSupplied = "fe_sendauth: no password supplied\n"

mutable struct _opaque_pthread_attr_t
    __sig::Clong
    __opaque::NTuple{56, UInt8}
end

mutable struct _opaque_pthread_cond_t
    __sig::Clong
    __opaque::NTuple{40, UInt8}
end

mutable struct _opaque_pthread_condattr_t
    __sig::Clong
    __opaque::NTuple{8, UInt8}
end

mutable struct _opaque_pthread_mutex_t
    __sig::Clong
    __opaque::NTuple{56, UInt8}
end

mutable struct _opaque_pthread_mutexattr_t
    __sig::Clong
    __opaque::NTuple{8, UInt8}
end

mutable struct _opaque_pthread_once_t
    __sig::Clong
    __opaque::NTuple{8, UInt8}
end

mutable struct _opaque_pthread_rwlock_t
    __sig::Clong
    __opaque::NTuple{192, UInt8}
end

mutable struct _opaque_pthread_rwlockattr_t
    __sig::Clong
    __opaque::NTuple{16, UInt8}
end

mutable struct _opaque_pthread_t
    __sig::Clong
    __cleanup_stack::Ptr{Cvoid}
    __opaque::NTuple{8176, UInt8}
end

# monstly generated, some I followed Apple's _types.h to resolve
const int8_t = UInt8
const int16_t = Int16
const int32_t = Cint
const int64_t = Clonglong
const u_int8_t = Cuchar
const u_int16_t = UInt16
const u_int32_t = UInt32
const u_int64_t = Culonglong
const register_t = Int64
const intptr_t = Clong
const uintptr_t = Culong
const user_addr_t = u_int64_t
const user_size_t = u_int64_t
const user_ssize_t = Int64
const user_long_t = Int64
const user_ulong_t = u_int64_t
const user_time_t = Int64
const user_off_t = Int64
const syscall_arg_t = u_int64_t
const va_list = Ptr{Cvoid}
const size_t = Culong
const fpos_t = int64_t
const FILE = Cvoid
const off_t = int64_t
const ssize_t = Clong
const Oid = UInt32
const pg_int64 = Clong

const OID_MAX = typemax(Oid)
InvalidOid() = Oid(0)

@enum(ConnStatusType::Cuint,
    CONNECTION_OK,
    CONNECTION_BAD,
    CONNECTION_STARTED,
    CONNECTION_MADE,
    CONNECTION_AWAITING_RESPONSE,
    CONNECTION_AUTH_OK,
    CONNECTION_SETENV,
    CONNECTION_SSL_STARTUP,
    CONNECTION_NEEDED,
)

@enum(PostgresPollingStatusType::Cuint,
    PGRES_POLLING_FAILED,
    PGRES_POLLING_READING,
    PGRES_POLLING_WRITING,
    PGRES_POLLING_OK,
    PGRES_POLLING_ACTIVE,
)

@enum(ExecStatusType::Cuint,
    PGRES_EMPTY_QUERY,
    PGRES_COMMAND_OK,
    PGRES_TUPLES_OK,
    PGRES_COPY_OUT,
    PGRES_COPY_IN,
    PGRES_BAD_RESPONSE,
    PGRES_NONFATAL_ERROR,
    PGRES_FATAL_ERROR,
    PGRES_COPY_BOTH,
    PGRES_SINGLE_TUPLE,
)

@enum(PGTransactionStatusType::Cuint,
    PQTRANS_IDLE,
    PQTRANS_ACTIVE,
    PQTRANS_INTRANS,
    PQTRANS_INERROR,
    PQTRANS_UNKNOWN,
)

@enum(PGVerbosity::Cuint,
    PQERRORS_TERSE,
    PQERRORS_DEFAULT,
    PQERRORS_VERBOSE,
)

@enum(PGContextVisibility::Cuint,
    PQSHOW_CONTEXT_NEVER,
    PQSHOW_CONTEXT_ERRORS,
    PQSHOW_CONTEXT_ALWAYS,
)

@enum(PGPing::Cuint,
    PQPING_OK,
    PQPING_REJECT,
    PQPING_NO_RESPONSE,
    PQPING_NO_ATTEMPT,
)

const PGconn = Cvoid

const PGresult = Cvoid

mutable struct pg_cancel
end

const PGcancel = Cvoid

mutable struct pgNotify
    relname::Cstring
    be_pid::Cint
    extra::Cstring
    next::Ptr{Cvoid}
end

const PGnotify = Cvoid
const PQnoticeReceiver = Ptr{Cvoid}
const PQnoticeProcessor = Ptr{Cvoid}
const pqbool = UInt8

mutable struct _PQprintOpt
    header::pqbool
    align::pqbool
    standard::pqbool
    html3::pqbool
    expanded::pqbool
    pager::pqbool
    fieldSep::Cstring
    tableOpt::Cstring
    caption::Cstring
    fieldName::Ptr{Cstring}
end

const PQprintOpt = Cvoid

struct PQconninfoOption
    keyword::Cstring
    envvar::Cstring
    compiled::Cstring
    val::Cstring
    label::Cstring
    dispchar::Cstring
    dispsize::Cint
end

const PQArgBlock = Cvoid

mutable struct pgresAttDesc
    name::Cstring
    tableid::Oid
    columnid::Cint
    format::Cint
    typid::Oid
    typlen::Cint
    atttypmod::Cint
end

const PGresAttDesc = Cvoid
const pgthreadlock_t = Ptr{Cvoid}

####################################### END COMMON #########################################

# Julia wrapper for header: /usr/local/opt/libpq/include/libpq-fe.h
# Automatically generated using Clang.jl wrap_c, version 0.0.0

function PQconnectStart(conninfo)
    ccall((:PQconnectStart, LIBPQ_HANDLE), Ptr{PGconn}, (Cstring,), conninfo)
end

function PQconnectStartParams(keywords, values, expand_dbname::Cint)
    ccall((:PQconnectStartParams, LIBPQ_HANDLE), Ptr{PGconn}, (Ptr{Ptr{UInt8}}, Ptr{Ptr{UInt8}}, Cint), keywords, values, expand_dbname)
end

function PQconnectPoll(conn)
    ccall((:PQconnectPoll, LIBPQ_HANDLE), PostgresPollingStatusType, (Ptr{PGconn},), conn)
end

function PQconnectdb(conninfo)
    ccall((:PQconnectdb, LIBPQ_HANDLE), Ptr{PGconn}, (Cstring,), conninfo)
end

function PQconnectdbParams(keywords, values, expand_dbname)
    ccall((:PQconnectdbParams, LIBPQ_HANDLE), Ptr{PGconn}, (Ptr{Ptr{UInt8}}, Ptr{Ptr{UInt8}}, Cint), keywords, values, expand_dbname)
end

function PQsetdbLogin(pghost, pgport, pgoptions, pgtty, dbName, login, pwd)
    ccall((:PQsetdbLogin, LIBPQ_HANDLE), Ptr{PGconn}, (Cstring, Cstring, Cstring, Cstring, Cstring, Cstring, Cstring), pghost, pgport, pgoptions, pgtty, dbName, login, pwd)
end

function PQfinish(conn)
    ccall((:PQfinish, LIBPQ_HANDLE), Cvoid, (Ptr{PGconn},), conn)
end

function PQconndefaults()
    ccall((:PQconndefaults, LIBPQ_HANDLE), Ptr{PQconninfoOption}, ())
end

function PQconninfoParse(conninfo, errmsg)
    ccall((:PQconninfoParse, LIBPQ_HANDLE), Ptr{PQconninfoOption}, (Cstring, Ptr{Ptr{UInt8}}), conninfo, errmsg)
end

function PQconninfo(conn)
    ccall((:PQconninfo, LIBPQ_HANDLE), Ptr{PQconninfoOption}, (Ptr{PGconn},), conn)
end

function PQconninfoFree(connOptions)
    ccall((:PQconninfoFree, LIBPQ_HANDLE), Cvoid, (Ptr{PQconninfoOption},), connOptions)
end

function PQresetStart(conn)
    ccall((:PQresetStart, LIBPQ_HANDLE), Cint, (Ptr{PGconn},), conn)
end

function PQresetPoll(conn)
    ccall((:PQresetPoll, LIBPQ_HANDLE), PostgresPollingStatusType, (Ptr{PGconn},), conn)
end

function PQreset(conn)
    ccall((:PQreset, LIBPQ_HANDLE), Cvoid, (Ptr{PGconn},), conn)
end

function PQgetCancel(conn)
    ccall((:PQgetCancel, LIBPQ_HANDLE), Ptr{PGcancel}, (Ptr{PGconn},), conn)
end

function PQfreeCancel(cancel)
    ccall((:PQfreeCancel, LIBPQ_HANDLE), Cvoid, (Ptr{PGcancel},), cancel)
end

function PQcancel(cancel, errbuf, errbufsize::Cint)
    ccall((:PQcancel, LIBPQ_HANDLE), Cint, (Ptr{PGcancel}, Cstring, Cint), cancel, errbuf, errbufsize)
end

function PQrequestCancel(conn)
    ccall((:PQrequestCancel, LIBPQ_HANDLE), Cint, (Ptr{PGconn},), conn)
end

function PQdb(conn)
    ccall((:PQdb, LIBPQ_HANDLE), Cstring, (Ptr{PGconn},), conn)
end

function PQuser(conn)
    ccall((:PQuser, LIBPQ_HANDLE), Cstring, (Ptr{PGconn},), conn)
end

function PQpass(conn)
    ccall((:PQpass, LIBPQ_HANDLE), Cstring, (Ptr{PGconn},), conn)
end

function PQhost(conn)
    ccall((:PQhost, LIBPQ_HANDLE), Cstring, (Ptr{PGconn},), conn)
end

function PQport(conn)
    ccall((:PQport, LIBPQ_HANDLE), Cstring, (Ptr{PGconn},), conn)
end

function PQtty(conn)
    ccall((:PQtty, LIBPQ_HANDLE), Cstring, (Ptr{PGconn},), conn)
end

function PQoptions(conn)
    ccall((:PQoptions, LIBPQ_HANDLE), Cstring, (Ptr{PGconn},), conn)
end

function PQstatus(conn)
    ccall((:PQstatus, LIBPQ_HANDLE), ConnStatusType, (Ptr{PGconn},), conn)
end

function PQtransactionStatus(conn)
    ccall((:PQtransactionStatus, LIBPQ_HANDLE), PGTransactionStatusType, (Ptr{PGconn},), conn)
end

function PQparameterStatus(conn, paramName)
    ccall((:PQparameterStatus, LIBPQ_HANDLE), Cstring, (Ptr{PGconn}, Cstring), conn, paramName)
end

function PQprotocolVersion(conn)
    ccall((:PQprotocolVersion, LIBPQ_HANDLE), Cint, (Ptr{PGconn},), conn)
end

function PQserverVersion(conn)
    ccall((:PQserverVersion, LIBPQ_HANDLE), Cint, (Ptr{PGconn},), conn)
end

function PQerrorMessage(conn)
    ccall((:PQerrorMessage, LIBPQ_HANDLE), Cstring, (Ptr{PGconn},), conn)
end

function PQsocket(conn)
    ccall((:PQsocket, LIBPQ_HANDLE), Cint, (Ptr{PGconn},), conn)
end

function PQbackendPID(conn)
    ccall((:PQbackendPID, LIBPQ_HANDLE), Cint, (Ptr{PGconn},), conn)
end

function PQconnectionNeedsPassword(conn)
    ccall((:PQconnectionNeedsPassword, LIBPQ_HANDLE), Cint, (Ptr{PGconn},), conn)
end

function PQconnectionUsedPassword(conn)
    ccall((:PQconnectionUsedPassword, LIBPQ_HANDLE), Cint, (Ptr{PGconn},), conn)
end

function PQclientEncoding(conn)
    ccall((:PQclientEncoding, LIBPQ_HANDLE), Cint, (Ptr{PGconn},), conn)
end

function PQsetClientEncoding(conn, encoding)
    ccall((:PQsetClientEncoding, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Cstring), conn, encoding)
end

function PQsslInUse(conn)
    ccall((:PQsslInUse, LIBPQ_HANDLE), Cint, (Ptr{PGconn},), conn)
end

function PQsslStruct(conn, struct_name)
    ccall((:PQsslStruct, LIBPQ_HANDLE), Ptr{Cvoid}, (Ptr{PGconn}, Cstring), conn, struct_name)
end

function PQsslAttribute(conn, attribute_name)
    ccall((:PQsslAttribute, LIBPQ_HANDLE), Cstring, (Ptr{PGconn}, Cstring), conn, attribute_name)
end

function PQsslAttributeNames(conn)
    ccall((:PQsslAttributeNames, LIBPQ_HANDLE), Ptr{Cstring}, (Ptr{PGconn},), conn)
end

function PQgetssl(conn)
    ccall((:PQgetssl, LIBPQ_HANDLE), Ptr{Cvoid}, (Ptr{PGconn},), conn)
end

function PQinitSSL(do_init::Cint)
    ccall((:PQinitSSL, LIBPQ_HANDLE), Cvoid, (Cint,), do_init)
end

function PQinitOpenSSL(do_ssl::Cint, do_crypto::Cint)
    ccall((:PQinitOpenSSL, LIBPQ_HANDLE), Cvoid, (Cint, Cint), do_ssl, do_crypto)
end

function PQsetErrorVerbosity(conn, verbosity::PGVerbosity)
    ccall((:PQsetErrorVerbosity, LIBPQ_HANDLE), PGVerbosity, (Ptr{PGconn}, PGVerbosity), conn, verbosity)
end

function PQsetErrorContextVisibility(conn, show_context::PGContextVisibility)
    ccall((:PQsetErrorContextVisibility, LIBPQ_HANDLE), PGContextVisibility, (Ptr{PGconn}, PGContextVisibility), conn, show_context)
end

function PQtrace(conn, debug_port)
    ccall((:PQtrace, LIBPQ_HANDLE), Cvoid, (Ptr{PGconn}, Ptr{FILE}), conn, debug_port)
end

function PQuntrace(conn)
    ccall((:PQuntrace, LIBPQ_HANDLE), Cvoid, (Ptr{PGconn},), conn)
end

function PQsetNoticeReceiver(conn, proc::PQnoticeReceiver, arg)
    ccall((:PQsetNoticeReceiver, LIBPQ_HANDLE), PQnoticeReceiver, (Ptr{PGconn}, PQnoticeReceiver, Ptr{Cvoid}), conn, proc, arg)
end

function PQsetNoticeProcessor(conn, proc::PQnoticeProcessor, arg)
    ccall((:PQsetNoticeProcessor, LIBPQ_HANDLE), PQnoticeProcessor, (Ptr{PGconn}, PQnoticeProcessor, Ptr{Cvoid}), conn, proc, arg)
end

function PQregisterThreadLock(newhandler::pgthreadlock_t)
    ccall((:PQregisterThreadLock, LIBPQ_HANDLE), pgthreadlock_t, (pgthreadlock_t,), newhandler)
end

function PQexec(conn, query)
    ccall((:PQexec, LIBPQ_HANDLE), Ptr{PGresult}, (Ptr{PGconn}, Cstring), conn, query)
end

function PQexecParams(conn, command, nParams, paramTypes, paramValues, paramLengths, paramFormats, resultFormat)
    ccall((:PQexecParams, LIBPQ_HANDLE), Ptr{PGresult}, (Ptr{PGconn}, Cstring, Cint, Ptr{Oid}, Ptr{Ptr{UInt8}}, Ptr{Cint}, Ptr{Cint}, Cint), conn, command, nParams, paramTypes, paramValues, paramLengths, paramFormats, resultFormat)
end

function PQprepare(conn, stmtName, query, nParams, paramTypes)
    ccall((:PQprepare, LIBPQ_HANDLE), Ptr{PGresult}, (Ptr{PGconn}, Cstring, Cstring, Cint, Ptr{Oid}), conn, stmtName, query, nParams, paramTypes)
end

function PQexecPrepared(conn, stmtName, nParams, paramValues, paramLengths, paramFormats, resultFormat)
    ccall((:PQexecPrepared, LIBPQ_HANDLE), Ptr{PGresult}, (Ptr{PGconn}, Cstring, Cint, Ptr{Ptr{UInt8}}, Ptr{Cint}, Ptr{Cint}, Cint), conn, stmtName, nParams, paramValues, paramLengths, paramFormats, resultFormat)
end

function PQsendQuery(conn, query)
    ccall((:PQsendQuery, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Cstring), conn, query)
end

function PQsendQueryParams(conn, command, nParams, paramTypes, paramValues, paramLengths, paramFormats, resultFormat)
    ccall((:PQsendQueryParams, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Cstring, Cint, Ptr{Oid}, Ptr{Ptr{UInt8}}, Ptr{Cint}, Ptr{Cint}, Cint), conn, command, nParams, paramTypes, paramValues, paramLengths, paramFormats, resultFormat)
end

function PQsendPrepare(conn, stmtName, query, nParams, paramTypes)
    ccall((:PQsendPrepare, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Cstring, Cstring, Cint, Ptr{Oid}), conn, stmtName, query, nParams, paramTypes)
end

function PQsendQueryPrepared(conn, stmtName, nParams, paramValues, paramLengths, paramFormats, resultFormat)
    ccall((:PQsendQueryPrepared, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Cstring, Cint, Ptr{Ptr{UInt8}}, Ptr{Cint}, Ptr{Cint}, Cint), conn, stmtName, nParams, paramValues, paramLengths, paramFormats, resultFormat)
end

function PQsetSingleRowMode(conn)
    ccall((:PQsetSingleRowMode, LIBPQ_HANDLE), Cint, (Ptr{PGconn},), conn)
end

function PQgetResult(conn)
    ccall((:PQgetResult, LIBPQ_HANDLE), Ptr{PGresult}, (Ptr{PGconn},), conn)
end

function PQisBusy(conn)
    ccall((:PQisBusy, LIBPQ_HANDLE), Cint, (Ptr{PGconn},), conn)
end

function PQconsumeInput(conn)
    ccall((:PQconsumeInput, LIBPQ_HANDLE), Cint, (Ptr{PGconn},), conn)
end

function PQnotifies(conn)
    ccall((:PQnotifies, LIBPQ_HANDLE), Ptr{PGnotify}, (Ptr{PGconn},), conn)
end

function PQputCopyData(conn, buffer, nbytes::Cint)
    ccall((:PQputCopyData, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Cstring, Cint), conn, buffer, nbytes)
end

function PQputCopyEnd(conn, errormsg)
    ccall((:PQputCopyEnd, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Cstring), conn, errormsg)
end

function PQgetCopyData(conn, buffer, async::Cint)
    ccall((:PQgetCopyData, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Ptr{Cstring}, Cint), conn, buffer, async)
end

function PQgetline(conn, string, length::Cint)
    ccall((:PQgetline, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Cstring, Cint), conn, string, length)
end

function PQputline(conn, string)
    ccall((:PQputline, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Cstring), conn, string)
end

function PQgetlineAsync(conn, buffer, bufsize::Cint)
    ccall((:PQgetlineAsync, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Cstring, Cint), conn, buffer, bufsize)
end

function PQputnbytes(conn, buffer, nbytes::Cint)
    ccall((:PQputnbytes, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Cstring, Cint), conn, buffer, nbytes)
end

function PQendcopy(conn)
    ccall((:PQendcopy, LIBPQ_HANDLE), Cint, (Ptr{PGconn},), conn)
end

function PQsetnonblocking(conn, arg::Cint)
    ccall((:PQsetnonblocking, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Cint), conn, arg)
end

function PQisnonblocking(conn)
    ccall((:PQisnonblocking, LIBPQ_HANDLE), Cint, (Ptr{PGconn},), conn)
end

function PQisthreadsafe()
    ccall((:PQisthreadsafe, LIBPQ_HANDLE), Cint, ())
end

function PQping(conninfo)
    ccall((:PQping, LIBPQ_HANDLE), PGPing, (Cstring,), conninfo)
end

function PQpingParams(keywords, values, expand_dbname::Cint)
    ccall((:PQpingParams, LIBPQ_HANDLE), PGPing, (Ptr{Ptr{UInt8}}, Ptr{Ptr{UInt8}}, Cint), keywords, values, expand_dbname)
end

function PQflush(conn)
    ccall((:PQflush, LIBPQ_HANDLE), Cint, (Ptr{PGconn},), conn)
end

function PQfn(conn, fnid::Cint, result_buf, result_len, result_is_int::Cint, args, nargs::Cint)
    ccall((:PQfn, LIBPQ_HANDLE), Ptr{PGresult}, (Ptr{PGconn}, Cint, Ptr{Cint}, Ptr{Cint}, Cint, Ptr{PQArgBlock}, Cint), conn, fnid, result_buf, result_len, result_is_int, args, nargs)
end

function PQresultStatus(res)
    ccall((:PQresultStatus, LIBPQ_HANDLE), ExecStatusType, (Ptr{PGresult},), res)
end

function PQresStatus(status::ExecStatusType)
    ccall((:PQresStatus, LIBPQ_HANDLE), Cstring, (ExecStatusType,), status)
end

function PQresultErrorMessage(res)
    ccall((:PQresultErrorMessage, LIBPQ_HANDLE), Cstring, (Ptr{PGresult},), res)
end

function PQresultVerboseErrorMessage(res, verbosity::PGVerbosity, show_context::PGContextVisibility)
    ccall((:PQresultVerboseErrorMessage, LIBPQ_HANDLE), Cstring, (Ptr{PGresult}, PGVerbosity, PGContextVisibility), res, verbosity, show_context)
end

function PQresultErrorField(res, fieldcode::Cint)
    ccall((:PQresultErrorField, LIBPQ_HANDLE), Cstring, (Ptr{PGresult}, Cint), res, fieldcode)
end

function PQntuples(res)
    ccall((:PQntuples, LIBPQ_HANDLE), Cint, (Ptr{PGresult},), res)
end

function PQnfields(res)
    ccall((:PQnfields, LIBPQ_HANDLE), Cint, (Ptr{PGresult},), res)
end

function PQbinaryTuples(res)
    ccall((:PQbinaryTuples, LIBPQ_HANDLE), Cint, (Ptr{PGresult},), res)
end

function PQfname(res, field_num)
    ccall((:PQfname, LIBPQ_HANDLE), Cstring, (Ptr{PGresult}, Cint), res, field_num)
end

function PQfnumber(res, field_name)
    ccall((:PQfnumber, LIBPQ_HANDLE), Cint, (Ptr{PGresult}, Cstring), res, field_name)
end

function PQftable(res, field_num)
    ccall((:PQftable, LIBPQ_HANDLE), Oid, (Ptr{PGresult}, Cint), res, field_num)
end

function PQftablecol(res, field_num)
    ccall((:PQftablecol, LIBPQ_HANDLE), Cint, (Ptr{PGresult}, Cint), res, field_num)
end

function PQfformat(res, field_num)
    ccall((:PQfformat, LIBPQ_HANDLE), Cint, (Ptr{PGresult}, Cint), res, field_num)
end

function PQftype(res, field_num)
    ccall((:PQftype, LIBPQ_HANDLE), Oid, (Ptr{PGresult}, Cint), res, field_num)
end

function PQfsize(res, field_num)
    ccall((:PQfsize, LIBPQ_HANDLE), Cint, (Ptr{PGresult}, Cint), res, field_num)
end

function PQfmod(res, field_num)
    ccall((:PQfmod, LIBPQ_HANDLE), Cint, (Ptr{PGresult}, Cint), res, field_num)
end

function PQcmdStatus(res)
    ccall((:PQcmdStatus, LIBPQ_HANDLE), Cstring, (Ptr{PGresult},), res)
end

function PQoidStatus(res)
    ccall((:PQoidStatus, LIBPQ_HANDLE), Cstring, (Ptr{PGresult},), res)
end

function PQoidValue(res)
    ccall((:PQoidValue, LIBPQ_HANDLE), Oid, (Ptr{PGresult},), res)
end

function PQcmdTuples(res)
    ccall((:PQcmdTuples, LIBPQ_HANDLE), Cstring, (Ptr{PGresult},), res)
end

function PQgetvalue(res, tup_num, field_num)
    ccall((:PQgetvalue, LIBPQ_HANDLE), Ptr{UInt8}, (Ptr{PGresult}, Cint, Cint), res, tup_num, field_num)
end

function PQgetlength(res, tup_num, field_num)
    ccall((:PQgetlength, LIBPQ_HANDLE), Cint, (Ptr{PGresult}, Cint, Cint), res, tup_num, field_num)
end

function PQgetisnull(res, tup_num, field_num)
    ccall((:PQgetisnull, LIBPQ_HANDLE), Cint, (Ptr{PGresult}, Cint, Cint), res, tup_num, field_num)
end

function PQnparams(res)
    ccall((:PQnparams, LIBPQ_HANDLE), Cint, (Ptr{PGresult},), res)
end

function PQparamtype(res, param_num)
    ccall((:PQparamtype, LIBPQ_HANDLE), Oid, (Ptr{PGresult}, Cint), res, param_num)
end

function PQdescribePrepared(conn, stmt)
    ccall((:PQdescribePrepared, LIBPQ_HANDLE), Ptr{PGresult}, (Ptr{PGconn}, Cstring), conn, stmt)
end

function PQdescribePortal(conn, portal)
    ccall((:PQdescribePortal, LIBPQ_HANDLE), Ptr{PGresult}, (Ptr{PGconn}, Cstring), conn, portal)
end

function PQsendDescribePrepared(conn, stmt)
    ccall((:PQsendDescribePrepared, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Cstring), conn, stmt)
end

function PQsendDescribePortal(conn, portal)
    ccall((:PQsendDescribePortal, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Cstring), conn, portal)
end

function PQclear(res)
    ccall((:PQclear, LIBPQ_HANDLE), Cvoid, (Ptr{PGresult},), res)
end

function PQfreemem(ptr)
    ccall((:PQfreemem, LIBPQ_HANDLE), Cvoid, (Ptr{Cvoid},), ptr)
end

function PQmakeEmptyPGresult(conn, status::ExecStatusType)
    ccall((:PQmakeEmptyPGresult, LIBPQ_HANDLE), Ptr{PGresult}, (Ptr{PGconn}, ExecStatusType), conn, status)
end

function PQcopyResult(src, flags::Cint)
    ccall((:PQcopyResult, LIBPQ_HANDLE), Ptr{PGresult}, (Ptr{PGresult}, Cint), src, flags)
end

function PQsetResultAttrs(res, numAttributes::Cint, attDescs)
    ccall((:PQsetResultAttrs, LIBPQ_HANDLE), Cint, (Ptr{PGresult}, Cint, Ptr{PGresAttDesc}), res, numAttributes, attDescs)
end

function PQresultAlloc(res, nBytes::Csize_t)
    ccall((:PQresultAlloc, LIBPQ_HANDLE), Ptr{Cvoid}, (Ptr{PGresult}, Csize_t), res, nBytes)
end

function PQsetvalue(res, tup_num::Cint, field_num::Cint, value, len::Cint)
    ccall((:PQsetvalue, LIBPQ_HANDLE), Cint, (Ptr{PGresult}, Cint, Cint, Cstring, Cint), res, tup_num, field_num, value, len)
end

function PQescapeStringConn(conn, to, from, length::Csize_t, error)
    ccall((:PQescapeStringConn, LIBPQ_HANDLE), Csize_t, (Ptr{PGconn}, Cstring, Cstring, Csize_t, Ptr{Cint}), conn, to, from, length, error)
end

function PQescapeLiteral(conn, str, len::Csize_t)
    ccall((:PQescapeLiteral, LIBPQ_HANDLE), Cstring, (Ptr{PGconn}, Cstring, Csize_t), conn, str, len)
end

function PQescapeIdentifier(conn, str, len::Csize_t)
    ccall((:PQescapeIdentifier, LIBPQ_HANDLE), Cstring, (Ptr{PGconn}, Cstring, Csize_t), conn, str, len)
end

function PQescapeByteaConn(conn, from, from_length::Csize_t, to_length)
    ccall((:PQescapeByteaConn, LIBPQ_HANDLE), Ptr{Cuchar}, (Ptr{PGconn}, Ptr{Cuchar}, Csize_t, Ptr{Csize_t}), conn, from, from_length, to_length)
end

function PQunescapeBytea(strtext, retbuflen::Ref{Csize_t})
    ccall((:PQunescapeBytea, LIBPQ_HANDLE), Ptr{Cuchar}, (Ptr{Cuchar}, Ref{Csize_t}), strtext, retbuflen)
end

function PQescapeString(to, from, length::Csize_t)
    ccall((:PQescapeString, LIBPQ_HANDLE), Csize_t, (Cstring, Cstring, Csize_t), to, from, length)
end

function PQescapeBytea(from, from_length::Csize_t, to_length)
    ccall((:PQescapeBytea, LIBPQ_HANDLE), Ptr{Cuchar}, (Ptr{Cuchar}, Csize_t, Ptr{Csize_t}), from, from_length, to_length)
end

function PQprint(fout, res, ps)
    ccall((:PQprint, LIBPQ_HANDLE), Cvoid, (Ptr{FILE}, Ptr{PGresult}, Ptr{PQprintOpt}), fout, res, ps)
end

function PQdisplayTuples(res, fp, fillAlign::Cint, fieldSep, printHeader::Cint, quiet::Cint)
    ccall((:PQdisplayTuples, LIBPQ_HANDLE), Cvoid, (Ptr{PGresult}, Ptr{FILE}, Cint, Cstring, Cint, Cint), res, fp, fillAlign, fieldSep, printHeader, quiet)
end

function PQprintTuples(res, fout, printAttName::Cint, terseOutput::Cint, width::Cint)
    ccall((:PQprintTuples, LIBPQ_HANDLE), Cvoid, (Ptr{PGresult}, Ptr{FILE}, Cint, Cint, Cint), res, fout, printAttName, terseOutput, width)
end

function lo_open(conn, lobjId::Oid, mode::Cint)
    ccall((:lo_open, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Oid, Cint), conn, lobjId, mode)
end

function lo_close(conn, fd::Cint)
    ccall((:lo_close, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Cint), conn, fd)
end

function lo_read(conn, fd::Cint, buf, len::Csize_t)
    ccall((:lo_read, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Cint, Cstring, Csize_t), conn, fd, buf, len)
end

function lo_write(conn, fd::Cint, buf, len::Csize_t)
    ccall((:lo_write, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Cint, Cstring, Csize_t), conn, fd, buf, len)
end

function lo_lseek(conn, fd::Cint, offset::Cint, whence::Cint)
    ccall((:lo_lseek, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Cint, Cint, Cint), conn, fd, offset, whence)
end

function lo_lseek64(conn, fd::Cint, offset::pg_int64, whence::Cint)
    ccall((:lo_lseek64, LIBPQ_HANDLE), pg_int64, (Ptr{PGconn}, Cint, pg_int64, Cint), conn, fd, offset, whence)
end

function lo_creat(conn, mode::Cint)
    ccall((:lo_creat, LIBPQ_HANDLE), Oid, (Ptr{PGconn}, Cint), conn, mode)
end

function lo_create(conn, lobjId::Oid)
    ccall((:lo_create, LIBPQ_HANDLE), Oid, (Ptr{PGconn}, Oid), conn, lobjId)
end

function lo_tell(conn, fd::Cint)
    ccall((:lo_tell, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Cint), conn, fd)
end

function lo_tell64(conn, fd::Cint)
    ccall((:lo_tell64, LIBPQ_HANDLE), pg_int64, (Ptr{PGconn}, Cint), conn, fd)
end

function lo_truncate(conn, fd::Cint, len::Csize_t)
    ccall((:lo_truncate, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Cint, Csize_t), conn, fd, len)
end

function lo_truncate64(conn, fd::Cint, len::pg_int64)
    ccall((:lo_truncate64, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Cint, pg_int64), conn, fd, len)
end

function lo_unlink(conn, lobjId::Oid)
    ccall((:lo_unlink, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Oid), conn, lobjId)
end

function lo_import(conn, filename)
    ccall((:lo_import, LIBPQ_HANDLE), Oid, (Ptr{PGconn}, Cstring), conn, filename)
end

function lo_import_with_oid(conn, filename, lobjId::Oid)
    ccall((:lo_import_with_oid, LIBPQ_HANDLE), Oid, (Ptr{PGconn}, Cstring, Oid), conn, filename, lobjId)
end

function lo_export(conn, lobjId::Oid, filename)
    ccall((:lo_export, LIBPQ_HANDLE), Cint, (Ptr{PGconn}, Oid, Cstring), conn, lobjId, filename)
end

function PQlibVersion()
    ccall((:PQlibVersion, LIBPQ_HANDLE), Cint, ())
end

function PQmblen(s, encoding::Cint)
    ccall((:PQmblen, LIBPQ_HANDLE), Cint, (Cstring, Cint), s, encoding)
end

function PQdsplen(s, encoding::Cint)
    ccall((:PQdsplen, LIBPQ_HANDLE), Cint, (Cstring, Cint), s, encoding)
end

function PQenv2encoding()
    ccall((:PQenv2encoding, LIBPQ_HANDLE), Cint, ())
end

function PQencryptPassword(passwd, user)
    ccall((:PQencryptPassword, LIBPQ_HANDLE), Cstring, (Cstring, Cstring), passwd, user)
end

function pg_char_to_encoding(name)
    ccall((:pg_char_to_encoding, LIBPQ_HANDLE), Cint, (Cstring,), name)
end

function pg_encoding_to_char(encoding::Cint)
    ccall((:pg_encoding_to_char, LIBPQ_HANDLE), Cstring, (Cint,), encoding)
end

function pg_valid_server_encoding_id(encoding::Cint)
    ccall((:pg_valid_server_encoding_id, LIBPQ_HANDLE), Cint, (Cint,), encoding)
end


text:
# # Logarithmic number system

# Computing basic functions like `power`, `exp` and `besselj` is not trivial for reversible programming.
# There is no efficient constant memory algorithm using pure fixed point numbers only.
# For example, to compute `x ^ n` reversiblly with fixed point numbers,
# we need to allocate a vector of size $O(n)$.
# With logarithmic numbers, the above computation is straight forward.

using LogarithmicNumbers
using NiLang, NiLang.AD
using FixedPointNumbers

@i function i_power(y::T, x::T, n::Int) where T
    if !iszero(x)
        @routine begin
            lx ← one(ULogarithmic{T})
            ly ← one(ULogarithmic{T})
            ## convert `x` to a logarithmic number
            ## Here, `*=` is reversible for log numbers
            if x > 0
                lx *= convert(x)
            else
                lx *= convert(-x)
            end
            for i=1:n
                ly *= lx
            end
        end

        ## convert back to fixed point numbers
        y += convert(ly)
        if x < 0 && n%2 == 1
            NEG(y)
        end

        ~@routine
    end
end

# To check the function
i_power(Fixed43(0.0), Fixed43(0.4), 3)

# ## `exp` function as an example
# The following example computes `exp(x)`.

@i function i_exp(y!::T, x::T) where T<:Union{Fixed, GVar{<:Fixed}}
    @invcheckoff begin
        @routine begin
            s ← one(ULogarithmic{T})
            lx ← one(ULogarithmic{T})
            k ← 0
        end
        lx *= convert(x)
        y! += convert(s)
        @from k==0 while s.log > -20
            k += 1
            s *= lx / k
            y! += convert(s)
        end
        ~(@from k==0 while s.log > -20
            k += 1
            s *= x / k
        end)
        lx /= convert(x)
        ~@routine
    end
end

x = Fixed43(3.5)

# We can check the reversibility
out, _ = i_exp(Fixed43(0.0), x)
@assert out ≈ exp(3.5)

# Computing the gradients
_, gx = NiLang.AD.gradient(Val(1), i_exp, (Fixed43(0.0), x))
@assert gx ≈ exp(3.5)


text:
function ngSpice_Init(printfcn, statfcn, ngexit, sdata, sinitdata, bgtrun, userData)
    ccall((:ngSpice_Init, libngspice), Cint, (Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}), printfcn, statfcn, ngexit, sdata, sinitdata, bgtrun, userData)
end

function ngSpice_Init_JLExtensions(path_resolve)
    ret = try;
        ccall((:ngSpice_Init_JLExtensions, libngspice), Cint, (Cint, Ptr{Cvoid},),
            1, path_resolve)
    catch e;
        @warn "Failed to initialize julia extensions. Some features may not work."
        return false
    end
    if ret != 0
        error("Failed to initialize julia extensions")
    end
    return true
end

function ngSpice_Init_Sync(vsrcdat, isrcdat, syncdat, ident, userData)
    ccall((:ngSpice_Init_Sync, libngspice), Cint, (Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cint}, Ptr{Cvoid}), vsrcdat, isrcdat, syncdat, ident, userData)
end

function ngSpice_Command(command)
    ccall((:ngSpice_Command, libngspice), Cint, (Cstring,), command)
end

function ngGet_Vec_Info(vecname)
    ccall((:ngGet_Vec_Info, libngspice), pvector_info, (Cstring,), vecname)
end

function ngSpice_Circ(circarray)
    ccall((:ngSpice_Circ, libngspice), Cint, (Ptr{Ptr{UInt8}},), circarray)
end

function ngSpice_CurPlot()
    ccall((:ngSpice_CurPlot, libngspice), Ptr{UInt8}, ())
end

function ngSpice_AllPlots()
    ccall((:ngSpice_AllPlots, libngspice), Ptr{Ptr{UInt8}}, ())
end

function ngSpice_AllVecs(plotname)
    ccall((:ngSpice_AllVecs, libngspice), Ptr{Ptr{UInt8}}, (Cstring,), plotname)
end

function ngSpice_running()
    ccall((:ngSpice_running, libngspice), Cint, ())
end

function ngSpice_SetBkpt(bkpt)
    ccall((:ngSpice_SetBkpt, libngspice), Cint, (Cdouble,), bkpt)
end

max_stars_repo_name: JuliaComputing/Ngspice

max_issues_repo_name: JuliaComputing/Ngspice

max_forks_repo_name: JuliaComputing/Ngspice


text:
## For computing a binned local polynomial
## regression estimator of a univariate regression
## function or its derivative.
## The data are discretised on an equally
## spaced grid. The bandwidths are discretised on a
## logarithmically spaced grid.
function locpoly(x::Vector{Float64}, y::Vector{Float64}, bandwidth::Union(Float64, Vector{Float64});
    drv::Int = 0,
    degree::Int=drv+1,
    kernel::Symbol = :normal,
    gridsize::Int = 401,
    bwdisc::Int = 25,
    range_x::Vector{Float64}=Float64[],
    binned::Bool = false,
    truncate::Bool = true)

    if any(bandwidth .<  0.0)
        error("'bandwidth' must be strictly positive")
    end

    if range_x == Float64[] && !binned
        maxx = maximum(x)
        minx = minimum(x)
        if y == Float64[]
            extra = 0.05 * (maxx - minx)
            range_x = [minx - extra, maxx + extra]
        else
            range_x = [minx, maxx]
        end
    end

    ## Rename common variables
    M = gridsize
    Q = bwdisc
    a = range_x[1]
    b = range_x[2]
    pp = degree + 1
    ppp = 2*degree + 1
    tau = 4

    ## Decide whether a density estimate or regression estimate is required.

    if y == Float64[]    # obtain density estimate
        n = length(x)
        gpoints = linspace(a, b, M)
        xcounts = linbin(x, gpoints, truncate)
        ycounts = (M-1) .* xcounts ./ (n*(b-a))
        xcounts = ones(M) #rep(1, M)
    else           # obtain regression estimate
        ## Bin the data if not already binned
        if !binned
            gpoints = linspace(a, b, M)
            xcounts, ycounts = rlbin(x, y, gpoints, truncate)
        else
            xcounts = x
            ycounts = y
            M = length(xcounts)
            gpoints = linspace(a, b, M)
        end
    end

    ## Set the bin width
    delta = (b-a)/(M-1)

    # Lvec = Int[]
    # hdisc = Float64[]
    # indic = Int[]
    # ## Discretise the bandwidths
    # if length(bandwidth) == M
    #     hlow = minimum(bandwidth)
    #     hupp = maximum(bandwidth)
    #     hdisc = [exp(h) for h in linspace(log(hlow),log(hupp),Q)]

    #     ## Determine value of L for each member of "hdisc"
    #     Lvec = [ifloor(tau*h/delta) for h in hdisc]

    #     ## Determine index of closest entry of "hdisc"
    #     ## to each member of "bandwidth"
    #     indic = if Q > 1
    #                 gap = (log(hdisc[Q])-log(hdisc[1]))/(Q-1)
    #                 if gap == 0
    #                     ones(Int, M)
    #                 else
    #                     lhlow = log(hlow)
    #                     [iround((log(b) - lhlow)/gap + 1.0) for b in bandwidth]
    #                 end
    #             else
    #                 ones(Int, M)
    #             end
    # elseif length(bandwidth) == 1
    #     indic = ones(Int, M)
    #     Q = 1
    #     Lvec = fill(ifloor(tau*bandwidth/delta), Q)
    #     hdisc = fill(bandwidth, Q)
    # else
    #     error("'bandwidth' must be a vector of length one or of length 'gridsize'")
    # end
    (indic, Q, Lvec, hdisc) = discretise_the_bandwidths(bandwidth, M, Q, tau, delta)

    if minimum(Lvec) == 0
        error("Binning grid too coarse for current (small) bandwidth: consider increasing 'gridsize'")
    end

    ## Allocate space for the kernel vector and final estimate

    dimfkap = 2 * sum(Lvec) + Q
    fkap = zeros(dimfkap)
    curvest = zeros(M)
    midpts = zeros(Int, Q)
    ss = zeros(M, ppp)
    tt = zeros(M, pp)
    Smat = zeros(pp, pp)
    Tvec = zeros(pp)
    ipvt = zeros(Int, pp)

    ccall((:locpol_, libkernsmooth), Ptr{Void},
      (Ptr{Float64}, Ptr{Float64}, Ptr{Int}, Ptr{Float64}, Ptr{Float64}, Ptr{Int}, Ptr{Int}, Ptr{Int},
       Ptr{Int}, Ptr{Int}, Ptr{Float64}, Ptr{Int}, Ptr{Int}, Ptr{Float64}, Ptr{Float64}, Ptr{Float64},
       Ptr{Float64}, Ptr{Int}, Ptr{Float64}),
      xcounts, ycounts,  &drv, &delta, hdisc, Lvec, indic, midpts, &M, &Q, fkap, &pp, &ppp,
      ss, tt, Smat, Tvec, ipvt, curvest)

    curvest = gamma(drv+1) .* curvest

    (gpoints, curvest)
end

locpoly(x::Vector{Float64}, bandwidth::Union(Float64, Vector{Float64}); args...) = locpoly(x, Float64[], bandwidth, args...)


text:
function update_mask(line, one_mask, zero_mask)
    one_mask = 0
    zero_mask = 0
    for idx in 1:36
        if line[7 + idx] == '1'
            one_mask |= 1 << (36 - idx)
        elseif line[7 + idx] == '0'
            zero_mask |= 1 << (36 - idx)
        end
    end
    return (zero_mask, one_mask)
end

function run(s)
    # Your code here
    one_mask::Int = 0
    zero_mask::Int = 0
    memory = Dict{Int,Int}()
    addr::Int = 0
    value::Int = 0
    for line in readlines(IOBuffer(s))
        if startswith(line, "mask")
            (zero_mask, one_mask) = update_mask(line, one_mask, zero_mask)
        else
            parts = split(line, " = ", limit=2)
            addr = parse(Int, SubString(parts[1], 5, lastindex(parts[1]) - 1))
            value = parse(Int, parts[2])
            memory[addr] = (value | one_mask) & ~zero_mask
        end
    end
    return sum(values(memory))
end

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

function main()
    res, time, memory = @timed run(ARGS[1])
    println("_duration:$(time * 1000)")
    println(res)
end

main()


text:
# benchmarks for ISDF in BSE

# %%
# loading packages
using BenchmarkTools, JLD2, FileIO, LinearAlgebra, FFTW
using BSE_k_ISDF

BLAS.set_num_threads(1)
FFTW.set_num_threads(1)

# general problem setup
isdir("1d") || mkdir("1d")

l = 1.5
V_sp = r -> 20 * cos(4π / l * r) + 0.2 * sin(2π / l * r)

V_func = (r_1, r_2) -> 1 /  sqrt((r_1 - r_2)^2 + 0.01)
W_func = (r_1, r_2, l, L) -> 0.0625 * (3.0 + sin(2π / l * r_1)) * (3.0 + cos(4π / l * r_2)) *
    exp(-abs(BSE_k_ISDF.supercell_difference(r_1, r_2, L))^2 / (2 * (4 * l)^2)) * V_func(BSE_k_ISDF.supercell_difference(r_1, r_2, L), 0.)

# %% benchmark different values of N_k

# fixed parameters
N_unit = 128

N_core = 0
N_v = 4
N_c = 5

N_μ_vv = 17
N_μ_cc = 23
N_μ_vc = 21

# variable parameters
N_k_vec = 2 .^(4:12)

for N_k in N_k_vec
    sp_prob = BSE_k_ISDF.SPProblem1D(V_sp, l, N_unit, N_k)
    prob = BSE_k_ISDF.BSEProblem1D(sp_prob, N_core, N_v, N_c, V_func, W_func)

    isdf = BSE_k_ISDF.ISDF(prob, N_μ_vv, N_μ_cc, N_μ_vc)
    t_isdf = @benchmark BSE_k_ISDF.ISDF($prob, $N_μ_vv, $N_μ_cc, $N_μ_vc)

    H = BSE_k_ISDF.setup_H(prob, isdf)
    t_H_setup = @benchmark BSE_k_ISDF.setup_H($prob, $isdf)

    x = rand(N_v * N_c * N_k) + im * rand(N_v * N_c * N_k)
    H * x
    t_H_x = @benchmark $H * $x

    save("1d/benchmark_$(N_k).jld2", "t_isdf", t_isdf, "t_H_setup", t_H_setup, "t_H_x", t_H_x)
end

# %% save results

results = [load("1d/benchmark_$(N_k).jld2") for N_k in N_k_vec]
timings = ["t_isdf", "t_H_setup", "t_H_x"]

setup_times = sum(1e-9 .* time.(minimum.([res[t] for res in results, t in timings[1:2]])); dims = 2)
evaluation_times = 1e-9 .* time.(minimum.([res[t] for res in results, t in timings[3:3]]))

save("1d/benchmark.jld2", "N_k_vec", N_k_vec, "setup_times", setup_times, "evaluation_times", evaluation_times)


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

function sum_reduce(x, istart, iend)
    s = zero(eltype(x))
    @simd for i = istart:iend
        @inbounds s += x[i]
    end
    s
end

function flog_sum_reduce( m, x )
    s = zero(eltype(x))
    for j=1:m
        # Try different starting and ending indices.
        sum_reduce(x,j,length(x)-(j-1))
    end
    s
end

for t in [Float32,Float64]
    n = 1000
    x = rand(t,n)
    bits = 8*sizeof(t)
    @timeit(flog_sum_reduce(100,x), "sum_reduction_$bits", "SIMD sum reduction over array of type $t", "SIMD")
end

max_stars_repo_name: JuliaTagBot/Benchmarks

max_issues_repo_name: JuliaArchive/Benchmarks

max_forks_repo_name: JuliaArchive/Benchmarks


text:
const Mesh = Cairo.CairoPattern

"""
    mesh(bezierpath::BezierPath,
         colors=Array{ColorTypes.Colorant, 1})

Create a mesh. The first three or four elements of the supplied `bezierpath`
define the three or four sides of the mesh shape.

The `colors` array define the color of each corner point. Colors are reused
if necessary. At least one color should be supplied.

Use `setmesh()` to select the mesh, which will be used to fill shapes.

# Example

```
@svg begin
    bp = makebezierpath(ngon(O, 50, 4, 0, vertices=true))
    mesh1 = mesh(bp, [
        "red",
        Colors.RGB(0, 1, 0),
        Colors.RGB(0, 1, 1),
        Colors.RGB(1, 0, 1)
        ])
    setmesh(mesh1)
    box(O, 500, 500, :fill)
end
```
"""
function mesh(bezierpath::BezierPath,
              colors=Array{ColorTypes.Colorant, 1})
    pattern = Cairo.CairoPatternMesh()
    Cairo.mesh_pattern_begin_patch(pattern)
    Cairo.mesh_pattern_move_to(pattern, bezierpath[1][1].x, bezierpath[1][1].y)
    vcount = 1
    for bp in bezierpath
        Cairo.mesh_pattern_curve_to(pattern, bp[2].x, bp[2].y, bp[3].x, bp[3].y, bp[4].x, bp[4].y)
        vcount >= 4 && break # 3, no more than 4, 5 is right out
        vcount += 1
    end
    if length(colors) > 0
        for n in 1:vcount
            # always use RGBA, even if RGB supplied
            col = convert(Colors.RGBA, parse(Colors.Colorant, colors[mod1(n, length(colors))]))
            Cairo.mesh_pattern_set_corner_color_rgba(pattern, n - 1, col.r, col.g, col.b, col.alpha)
        end
    end
	Cairo.mesh_pattern_end_patch(pattern)
    return pattern
end

# old style for compatibility
mesh(bezierpath::Array{NTuple{4, Point}}, colors=Array{ColorTypes.Colorant, 1}) =
    mesh(BezierPath(bezierpath), colors)

"""
    mesh(points::Array{Point},
         colors=Array{ColorTypes.Colorant, 1})

Create a mesh.

Create a mesh. The first three or four sides of the supplied `points` polygon
define the three or four sides of the mesh shape.

The `colors` array define the color of each corner point. Colors are reused
if necessary. At least one color should be supplied.

# Example
```
@svg begin
    pl = ngon(O, 250, 3, pi/6, vertices=true)
    mesh1 = mesh(pl, [
        "purple",
        Colors.RGBA(0.0, 1.0, 0.5, 0.5),
        "yellow"
        ])
    setmesh(mesh1)
    setline(180)
    ngon(O, 250, 3, pi/6, :strokepreserve)
    setline(5)
    sethue("black")
    strokepath()
end
```
"""
function mesh(plist::Array{Point},
              colors=Array{ColorTypes.Colorant, 1})
    pattern = Cairo.CairoPatternMesh()
    Cairo.mesh_pattern_begin_patch(pattern)
    Cairo.mesh_pattern_move_to(pattern, plist[1].x, plist[1].y)
    # we must do 3 or 4 vertices
    vcount = 1
    for pt in plist[2:end]
        Cairo.mesh_pattern_line_to(pattern, pt.x, pt.y)
        vcount >= 5 && break
        vcount += 1
    end
    if length(colors) > 0
        for n in 1:vcount
            # always use RGBA, even if RGB supplied
            col = convert(Colors.RGBA, parse(Colors.Colorant, colors[mod1(n, length(colors))]))
            Cairo.mesh_pattern_set_corner_color_rgba(pattern, n - 1, col.r, col.g, col.b, col.alpha)
        end
    end
	Cairo.mesh_pattern_end_patch(pattern)
    return pattern
end

"""
    setmesh(mesh::Mesh)

Select a mesh previously created with `mesh()` for filling shapes.
"""
function setmesh(m::Mesh)
    Cairo.set_source(get_current_cr(), m)
end


text:
transD_GP.getchi2forall(opt)
##
opt.xall[:] .= zall
transD_GP.plot_posterior(tempest, opt, burninfrac=0.5, figsize=(10,6), cmappdf="hot",
        qp1=0.05, qp2=0.95, nbins=200, vmaxpc=1)
ax = gcf().axes
ax[1].invert_xaxis()
ax[1].step(log10.(ρ[2:end]), z[2:end], color="r", alpha=0.5)
ax[1].step(log10.(ρ[2:end]), z[2:end], color="m", alpha=0.5, linestyle="--")
ax[2].set_ylim(280,0)
## nuisance histograms
transD_GP.plot_posterior(tempest, optn, burninfrac=0.5, nbins=50)

max_stars_repo_name: GeoscienceAustralia/HiQGA

max_issues_repo_name: GeoscienceAustralia/HiQGA


text:
using Test, DiscreteExteriorCalculus
const DEC = DiscreteExteriorCalculus
using LinearAlgebra: eigen
using AdmittanceModels: sparse_nullbasis
using Base.Iterators: product
using UniqueVectors: UniqueVector

r1, r2 = .5, .4
num = 40
points, tcomp = DEC.triangulated_lattice([r1, 0], [0, r2], num, num)

N, K = 2, 3
@test typeof(tcomp) <: TriangulatedComplex{N, K}

orient!(tcomp.complex)
m = Metric(N)
mesh = Mesh(tcomp, circumcenter(m))

laplacian = differential_operator(m, mesh, "Δ", 1, true)
comp = tcomp.complex
_, exterior = boundary_components_connected(comp)
constraint = zero_constraint(comp, exterior.cells[1], 1)
nullbasis = sparse_nullbasis(constraint)

vals, vects = eigen(collect(transpose(nullbasis) * laplacian * nullbasis))
inds = sortperm(vals)
vals, vects = vals[inds], vects[:, inds]

# solution is ψ(x,y) = sin(m*π*x/R1)*sin(n*π*y/R2) for integers m and n
function rect_vecs(m, n)
    v = zeros(num+1, num+1)
    for i in 1:(num+1)
        for j in 1:(num+1)
            x, y = (i-1)/num, (j-1)/num
            v[i, j] = sin(m*π*x)*sin(n*π*y)
        end
    end
    return v
end
rect_vals(m, n, R1, R2) = (m * π/R1)^2 + (n * π/R2)^2
l = 16
correct_vals = [rect_vals(i,j,r1,r2) for (i,j) in vcat(product(1:l, 1:l)...)]
correct_inds = sortperm(correct_vals)[1:l]

correct_vs = [rect_vecs(i,j)
    for (i,j) in vcat(product(1:l, 1:l)...)[correct_inds]]
comp_points = UniqueVector([c.points[1] for c in comp.cells[1]])
ordering = [findfirst(isequal(p), comp_points) for p in points]
vs = [collect(transpose(reshape((nullbasis * vects[:,i])[ordering],
    num+1, num+1))) for i in 1:l]
for i in 1:l
    vs[i] /= maximum(abs.(vs[i]))
    j = argmax(abs.(correct_vs[i]))
    if vs[i][j] * correct_vs[i][j] < 0
        vs[i] *= -1
    end
end

@testset "laplacian on a rectangle" begin
    @test isapprox(vals[1:l], correct_vals[correct_inds], rtol=1e-2)
    @test isapprox(vs, correct_vs, rtol=1e-2)
end

if false # set to true to make heatmap plots of modes
    using PlotlyJS: plot, heatmap
    plot(heatmap(z=vs[1]))
end


text:
#################################################################################
# Comments
#
# - Ideally the net_injection variables would be bounded.  This can be done using an adhoc data model extention
# - the `instantiate_*_expr_model` functions combine `PM.instantiate_model` and the `build_*` methods
#################################################################################
# Model Definitions

function instantiate_nip_expr_model(data::Dict{String, Any}, model_constructor; kwargs...)
    return PM.instantiate_model(data, model_constructor, instantiate_nip_expr; kwargs...)
end

# replicates PM.build_mn_opf
function instantiate_nip_expr(pm::PM.AbstractPowerModel)
    for n in eachindex(PM.nws(pm))
        @assert !PM.ismulticonductor(pm, nw=n)
        PM.variable_bus_voltage(pm, nw=n)
        PM.variable_branch_power(pm, nw=n; bounded=false)
        PM.variable_dcline_power(pm, nw=n; bounded=false)

        PM.constraint_model_voltage(pm, nw=n)

        for i in PM.ids(pm, :ref_buses, nw=n)
            PM.constraint_theta_ref(pm, i, nw=n)
        end

        for i in PM.ids(pm, :bus, nw=n)
            constraint_power_balance_ni_expr(pm, i, nw=n)
        end

        for i in PM.ids(pm, :branch, nw=n)
            PM.constraint_ohms_yt_from(pm, i, nw=n)
            PM.constraint_ohms_yt_to(pm, i, nw=n)

            PM.constraint_voltage_angle_difference(pm, i, nw=n)
        end

        for i in PM.ids(pm, :dcline, nw=n)
            PM.constraint_dcline_power_losses(pm, i, nw=n)
        end
    end

    return
end

function instantiate_nip_ptdf_expr_model(
    data::Dict{String, Any},
    model_constructor;
    kwargs...,
)
    return PM.instantiate_model(
        data,
        PM.DCPPowerModel,
        instantiate_nip_ptdf_expr;
        ref_extensions=[PM.ref_add_connected_components!, PM.ref_add_sm!],
        kwargs...,
    )
end

# replicates PM.build_opf_ptdf
function instantiate_nip_ptdf_expr(pm::PM.AbstractPowerModel)
    for n in eachindex(PM.nws(pm))
        @assert !PM.ismulticonductor(pm, nw=n)

        #PM.variable_gen_power(pm) #connect P__* with these

        for i in PM.ids(pm, :bus, nw=n)
            if !haskey(PM.var(pm, n), :inj_p)
                PM.var(pm, n)[:inj_p] = Dict{Int, Any}()
            end
            PM.var(pm, n, :inj_p)[i] = PM.ref(pm, :bus, i, nw=n)["inj_p"] # use :nodal_balance_expr
        end

        PM.constraint_model_voltage(pm, nw=n)

        # this constraint is implicit in this model
        #for i in PM.ids(pm, :ref_buses, nw = n)
        #    PM.constraint_theta_ref(pm, i, nw = n)
        #end

        # done later with PSI copper_plate
        #for i in PM.ids(pm, :bus, nw = n)
        #    constraint_power_balance_ni_expr(pm, i, nw = n)
        #end
        for (i, branch) in PM.ref(pm, :branch, nw=n)
            if haskey(branch, "rate_a")
                PM.expression_branch_power_ohms_yt_from_ptdf(pm, i, nw=n)
                PM.expression_branch_power_ohms_yt_to_ptdf(pm, i, nw=n)
            end

            # done in PSI construct_branch!
            #PM.constraint_thermal_limit_from(pm, i, nw = n)
            #PM.constraint_thermal_limit_to(pm, i, nw = n)
        end
    end

    return
end

function instantiate_bfp_expr_model(data::Dict{String, Any}, model_constructor; kwargs...)
    return PM.instantiate_model(data, model_constructor, instantiate_bfp_expr; kwargs...)
end

# replicates PM.build_mn_opf_bf_strg
function instantiate_bfp_expr(pm::PM.AbstractPowerModel)
    for n in eachindex(PM.nws(pm))
        @assert !PM.ismulticonductor(pm, nw=n)
        PM.variable_bus_voltage(pm, nw=n)
        PM.variable_branch_power(pm, nw=n; bounded=false)
        PM.variable_dcline_power(pm, nw=n; bounded=false)

        PM.constraint_model_current(pm, nw=n)

        for i in PM.ids(pm, :ref_buses, nw=n)
            PM.constraint_theta_ref(pm, i, nw=n)
        end

        for i in PM.ids(pm, :bus, nw=n)
            constraint_power_balance_ni_expr(pm, i, nw=n)
        end

        for i in PM.ids(pm, :branch, nw=n)
            PM.constraint_power_losses(pm, i, nw=n)
            PM.constraint_voltage_magnitude_difference(pm, i, nw=n)

            PM.constraint_voltage_angle_difference(pm, i, nw=n)
        end

        for i in PM.ids(pm, :dcline, nw=n)
            PM.constraint_dcline_power_losses(pm, i, nw=n)
        end
    end

    return
end

function instantiate_vip_expr_model(data::Dict{String, Any}, model_constructor; kwargs...)
    throw(error("VI Models not currently supported"))
end

#################################################################################
# Model Extention Functions

function constraint_power_balance_ni_expr(pm::PM.AbstractPowerModel, i::Int; nw::Int=pm.cnw)
    if !haskey(PM.con(pm, nw), :power_balance_p)
        PM.con(pm, nw)[:power_balance_p] = Dict{Int, JuMP.ConstraintRef}()
    end
    if !haskey(PM.con(pm, nw), :power_balance_q)
        PM.con(pm, nw)[:power_balance_q] = Dict{Int, JuMP.ConstraintRef}()
    end

    bus_arcs = PM.ref(pm, nw, :bus_arcs, i)
    bus_arcs_dc = PM.ref(pm, nw, :bus_arcs_dc, i)

    inj_p_expr = PM.ref(pm, nw, :bus, i, "inj_p")
    inj_q_expr = PM.ref(pm, nw, :bus, i, "inj_q")

    constraint_power_balance_ni_expr(
        pm,
        nw,
        i,
        bus_arcs,
        bus_arcs_dc,
        inj_p_expr,
        inj_q_expr,
    )

    return
end

function constraint_power_balance_ni_expr(
    pm::PM.AbstractPowerModel,
    n::Int,
    i::Int,
    bus_arcs,
    bus_arcs_dc,
    inj_p_expr,
    inj_q_expr,
)
    p = PM.var(pm, n, :p)
    q = PM.var(pm, n, :q)
    p_dc = PM.var(pm, n, :p_dc)
    q_dc = PM.var(pm, n, :q_dc)

    PM.con(pm, n, :power_balance_p)[i] = JuMP.@constraint(
        pm.model,
        sum(p[a] for a in bus_arcs) + sum(p_dc[a_dc] for a_dc in bus_arcs_dc) == inj_p_expr
    )
    PM.con(pm, n, :power_balance_q)[i] = JuMP.@constraint(
        pm.model,
        sum(q[a] for a in bus_arcs) + sum(q_dc[a_dc] for a_dc in bus_arcs_dc) == inj_q_expr
    )

    return
end

function constraint_current_balance_ni_expr(
    pm::PM.AbstractPowerModel,
    i::Int;
    nw::Int=pm.cnw,
)
    if !haskey(PM.con(pm, nw), :kcl_cr)
        PM.con(pm, nw)[:kcl_cr] = Dict{Int, JuMP.ConstraintRef}()
    end
    if !haskey(PM.con(pm, nw), :kcl_ci)
        PM.con(pm, nw)[:kcl_ci] = Dict{Int, JuMP.ConstraintRef}()
    end

    bus_arcs = PM.ref(pm, nw, :bus_arcs, i)
    bus_arcs_dc = PM.ref(pm, nw, :bus_arcs_dc, i)

    inj_p_expr = PM.ref(pm, nw, :bus, i, "inj_p")
    inj_q_expr = PM.ref(pm, nw, :bus, i, "inj_q")

    constraint_current_balance_ni_expr(
        pm,
        nw,
        i,
        bus_arcs,
        bus_arcs_dc,
        inj_p_expr,
        inj_q_expr,
    )

    return
end

function constraint_current_balance_ni_expr(
    pm::PM.AbstractPowerModel,
    n::Int,
    i::Int,
    bus_arcs,
    bus_arcs_dc,
    inj_p_expr,
    inj_q_expr,
)
    p = PM.var(pm, n, :p)
    q = PM.var(pm, n, :q)
    p_dc = PM.var(pm, n, :p_dc)
    q_dc = PM.var(pm, n, :q_dc)

    PM.con(pm, n, :power_balance_p)[i] = JuMP.@constraint(
        pm.model,
        sum(p[a] for a in bus_arcs) + sum(p_dc[a_dc] for a_dc in bus_arcs_dc) == inj_p_expr
    )
    PM.con(pm, n, :power_balance_q)[i] = JuMP.@constraint(
        pm.model,
        sum(q[a] for a in bus_arcs) + sum(q_dc[a_dc] for a_dc in bus_arcs_dc) == inj_q_expr
    )

    return
end

"""
active power only models ignore reactive power variables
"""
function variable_reactive_net_injection(pm::PM.AbstractActivePowerModel; kwargs...)
    return
end

function constraint_power_balance_ni_expr(
    pm::PM.AbstractActivePowerModel,
    n::Int,
    i::Int,
    bus_arcs,
    bus_arcs_dc,
    inj_p_expr,
    _,
)
    p = PM.var(pm, n, :p)
    p_dc = PM.var(pm, n, :p_dc)

    PM.con(pm, n, :power_balance_p)[i] = JuMP.@constraint(
        pm.model,
        sum(p[a] for a in bus_arcs) + sum(p_dc[a_dc] for a_dc in bus_arcs_dc) == inj_p_expr
    )

    return
end

function powermodels_network!(
    container::OptimizationContainer,
    system_formulation::Type{S},
    sys::PSY.System,
    template::ProblemTemplate,
    instantiate_model=instantiate_nip_expr_model,
) where {S <: PM.AbstractPowerModel}
    time_steps = get_time_steps(container)
    pm_data, PM_map = pass_to_pm(sys, template, time_steps[end])
    buses = PSY.get_components(PSY.Bus, sys)

    for t in time_steps, bus in buses
        pm_data["nw"]["$(t)"]["bus"]["$(bus.number)"]["inj_p"] =
            container.expressions[ExpressionKey(ActivePowerBalance, PSY.Bus)][bus.number, t]
        pm_data["nw"]["$(t)"]["bus"]["$(bus.number)"]["inj_q"] =
            container.expressions[ExpressionKey(ReactivePowerBalance, PSY.Bus)][
                bus.number,
                t,
            ]
    end

    container.pm =
        instantiate_model(pm_data, system_formulation, jump_model=container.JuMPmodel)
    container.pm.ext[:PMmap] = PM_map

    return
end

function powermodels_network!(
    container::OptimizationContainer,
    system_formulation::Type{S},
    sys::PSY.System,
    template::ProblemTemplate,
    instantiate_model=instantiate_nip_expr_model,
) where {S <: PM.AbstractActivePowerModel}
    time_steps = get_time_steps(container)
    pm_data, PM_map = pass_to_pm(sys, template, time_steps[end])
    buses = PSY.get_components(PSY.Bus, sys)

    for t in time_steps, bus in buses
        pm_data["nw"]["$(t)"]["bus"]["$(PSY.get_number(bus))"]["inj_p"] =
            container.expressions[ExpressionKey(ActivePowerBalance, PSY.Bus)][
                PSY.get_number(bus),
                t,
            ]
        # pm_data["nw"]["$(t)"]["bus"]["$(bus.number)"]["inj_q"] = 0.0
    end

    container.pm =
        instantiate_model(pm_data, system_formulation, jump_model=container.JuMPmodel)
    container.pm.ext[:PMmap] = PM_map

    return
end

#### PM accessor functions ########

function PMvarmap(::Type{S}) where {S <: PM.AbstractDCPModel}
    pm_variable_map = Dict{Type, Dict{Symbol, Union{VariableType, NamedTuple}}}()

    pm_variable_map[PSY.Bus] = Dict(:va => VoltageAngle())
    pm_variable_map[PSY.ACBranch] =
        Dict(:p => (from_to=FlowActivePowerVariable(), to_from=nothing))
    pm_variable_map[PSY.DCBranch] =
        Dict(:p_dc => (from_to=FlowActivePowerVariable(), to_from=nothing))

    return pm_variable_map
end

function PMvarmap(::Type{S}) where {S <: PM.AbstractActivePowerModel}
    pm_variable_map = Dict{Type, Dict{Symbol, Union{VariableType, NamedTuple}}}()

    pm_variable_map[PSY.Bus] = Dict(:va => VoltageAngle())
    pm_variable_map[PSY.ACBranch] = Dict(:p => FlowActivePowerFromToVariable())
    pm_variable_map[PSY.DCBranch] = Dict(
        :p_dc => (
            from_to=FlowActivePowerFromToVariable(),
            to_from=FlowActivePowerToFromVariable(),
        ),
    )

    return pm_variable_map
end

function PMvarmap(::Type{PTDFPowerModel})
    pm_variable_map = Dict{Type, Dict{Symbol, Union{String, NamedTuple}}}()

    pm_variable_map[PSY.Bus] = Dict()
    pm_variable_map[PSY.ACBranch] = Dict()
    pm_variable_map[PSY.DCBranch] = Dict()

    return pm_variable_map
end

function PMvarmap(::Type{S}) where {S <: PM.AbstractPowerModel}
    pm_variable_map = Dict{Type, Dict{Symbol, Union{VariableType, NamedTuple}}}()

    pm_variable_map[PSY.Bus] = Dict(:va => VoltageAngle(), :vm => VoltageMagnitude())
    pm_variable_map[PSY.ACBranch] = Dict(
        :p => (
            from_to=FlowActivePowerFromToVariable(),
            to_from=FlowActivePowerToFromVariable(),
        ),
        :q => (
            from_to=FlowReactivePowerFromToVariable(),
            to_from=FlowReactivePowerToFromVariable(),
        ),
    )
    pm_variable_map[PSY.DCBranch] = Dict(
        :p_dc => (from_to=FlowActivePowerVariable(), to_from=nothing),
        :q_dc => (
            from_to=FlowReactivePowerFromToVariable(),
            to_from=FlowReactivePowerToFromVariable(),
        ),
    )

    return pm_variable_map
end

function PMconmap(::Type{S}) where {S <: PM.AbstractActivePowerModel}
    pm_constraint_map = Dict{Type, Dict{Symbol, <:ConstraintType}}()

    pm_constraint_map[PSY.Bus] = Dict(:power_balance_p => NodalBalanceActiveConstraint())
    return pm_constraint_map
end

function PMconmap(::Type{S}) where {S <: PM.AbstractPowerModel}
    pm_constraint_map = Dict{Type, Dict{Symbol, ConstraintType}}()

    pm_constraint_map[PSY.Bus] = Dict(
        :power_balance_p => NodalBalanceActiveConstraint(),
        :power_balance_q => NodalBalanceReactiveConstraint(),
    )
    return pm_constraint_map
end

function PMexprmap(::Type{S}) where {S <: PM.AbstractPowerModel}
    pm_expr_map = Dict{
        Type,
        NamedTuple{
            (:pm_expr, :psi_con),
            Tuple{Dict{Symbol, Union{VariableType, NamedTuple}}, Symbol},
        },
    }()

    return pm_expr_map
end

function PMexprmap(::Type{PTDFPowerModel})
    pm_expr_map = Dict{
        Type,
        NamedTuple{
            (:pm_expr, :psi_con),
            Tuple{Dict{Symbol, Union{VariableType, NamedTuple}}, ConstraintType},
        },
    }()

    pm_expr_map[PSY.ACBranch] = (
        pm_expr=Dict(:p => (from_to=FlowActivePowerVariable(), to_from=nothing)),
        psi_con=NetworkFlowConstraint(),
    )

    return pm_expr_map
end

function add_pm_variable_refs!(
    container::OptimizationContainer,
    system_formulation::Type{S},
    ::PSY.System,
) where {S <: PM.AbstractPowerModel}
    time_steps = get_time_steps(container)
    bus_dict = container.pm.ext[:PMmap].bus
    ACbranch_dict = container.pm.ext[:PMmap].arcs
    ACbranch_types = typeof.(values(ACbranch_dict))
    DCbranch_dict = container.pm.ext[:PMmap].arcs_dc
    DCbranch_types = typeof.(values(DCbranch_dict))

    pm_variable_types = keys(PM.var(container.pm, 1))

    pm_variable_map = PMvarmap(system_formulation)
    bus_names = [PSY.get_name(b) for b in values(bus_dict)]
    for (pm_v, ps_v) in pm_variable_map[PSY.Bus]
        if pm_v in pm_variable_types
            var_container =
                add_variable_container!(container, ps_v, PSY.Bus, bus_names, time_steps)
            for t in time_steps, (pm_bus, bus) in bus_dict
                name = PSY.get_name(bus)
                var_container[name, t] = PM.var(container.pm, t, pm_v)[pm_bus] # pm_vars[pm_v][pm_bus]
            end
        end
    end

    add_pm_variable_refs!(
        container,
        PSY.ACBranch,
        ACbranch_types,
        ACbranch_dict,
        pm_variable_map,
        pm_variable_types,
        time_steps,
    )
    add_pm_variable_refs!(
        container,
        PSY.DCBranch,
        DCbranch_types,
        DCbranch_dict,
        pm_variable_map,
        pm_variable_types,
        time_steps,
    )
    return
end

function add_pm_variable_refs!(
    container::OptimizationContainer,
    d_class::Type,
    device_types::Vector,
    pm_map::Dict,
    pm_variable_map::Dict,
    pm_variable_types::Base.KeySet,
    time_steps::UnitRange{Int},
)
    for d_type in Set(device_types)
        devices = [d for d in pm_map if typeof(d[2]) == d_type]
        for (pm_v, ps_v) in pm_variable_map[d_class]
            if pm_v in pm_variable_types
                for dir in fieldnames(typeof(ps_v))
                    var_type = getfield(ps_v, dir)
                    var_type === nothing && continue
                    var_container = add_variable_container!(
                        container,
                        var_type,
                        d_type,
                        [PSY.get_name(d[2]) for d in devices],
                        time_steps,
                    )
                    for t in time_steps, (pm_d, d) in devices
                        var = PM.var(container.pm, t, pm_v, getfield(pm_d, dir))
                        var_container[PSY.get_name(d), t] = var
                    end
                end
            end
        end
    end
end

function add_pm_constraint_refs!(
    container::OptimizationContainer,
    system_formulation::Type{S},
    ::PSY.System,
) where {S <: PM.AbstractPowerModel}
    time_steps = get_time_steps(container)
    bus_dict = container.pm.ext[:PMmap].bus

    pm_constraint_names =
        [k for k in keys(PM.con(container.pm, 1)) if !isempty(PM.con(container.pm, 1, k))]

    pm_constraint_map = PMconmap(system_formulation)
    for (pm_v, ps_v) in pm_constraint_map[PSY.Bus]
        if pm_v in pm_constraint_names
            cons_container = add_constraints_container!(
                container,
                ps_v,
                PSY.Bus,
                [PSY.get_name(b) for b in values(bus_dict)],
                time_steps,
            )
            for t in time_steps, (pm_bus, bus) in bus_dict
                name = PSY.get_name(bus)
                cons_container[name, t] = PM.con(container.pm, t, pm_v)[pm_bus]
            end
        end
    end
end

function add_pm_expr_refs!(
    container::OptimizationContainer,
    system_formulation::Type{S},
    ::PSY.System,
) where {S <: PM.AbstractPowerModel}
    time_steps = get_time_steps(container)

    ACbranch_dict = container.pm.ext[:PMmap].arcs
    ACbranch_types = typeof.(values(ACbranch_dict))

    pm_variable_types = keys(PM.var(container.pm, 1))
    pm_expr_map = PMexprmap(system_formulation)

    add_pm_expr_refs!(
        container,
        PSY.ACBranch,
        ACbranch_types,
        ACbranch_dict,
        pm_expr_map,
        pm_variable_types,
        time_steps,
    )
    return
end

function add_pm_expr_refs!(
    container::OptimizationContainer,
    d_class::Type,
    device_types::Vector,
    pm_map::Dict,
    pm_expr_map::Dict,
    pm_variable_types::Base.KeySet,
    time_steps::UnitRange{Int},
)
    for d_type in Set(device_types)
        for (pm_expr_var, ps_v) in pm_expr_map[d_class].pm_expr
            if pm_expr_var in pm_variable_types
                pm_devices = keys(PM.var(container.pm, pm_expr_var, nw=1))
                mapped_pm_devices = Vector()
                mapped_ps_devices = Vector{d_type}()
                for d in pm_map
                    if typeof(d[2]) == d_type &&
                       d[1].from_to ∈ pm_devices &&
                       d[1].to_from ∈ pm_devices
                        push!(mapped_pm_devices, d[1])
                        push!(mapped_ps_devices, d[2])
                    end
                end
                isempty(mapped_ps_devices) && continue
                mapped_ps_device_names = PSY.get_name.(mapped_ps_devices)

                # add variable in psi
                # add psi_var = pm_expr_var as constraint
                for dir in fieldnames(typeof(ps_v))
                    var_type = getfield(ps_v, dir)
                    var_type === nothing && continue

                    add_variable!(
                        container,
                        var_type,
                        mapped_ps_devices,
                        StaticBranchUnbounded(),
                    )
                    psi_variable_container = get_variable(container, var_type, d_type)

                    con_type = pm_expr_map[d_class].psi_con
                    psi_constraint_container = add_constraints_container!(
                        container,
                        con_type,
                        d_type,
                        mapped_ps_device_names,
                        time_steps,
                    )
                    for t in time_steps,
                        (pm_d, name) in zip(mapped_pm_devices, mapped_ps_device_names)

                        pm_expr = PM.var(container.pm, t, pm_expr_var, getfield(pm_d, dir))
                        psi_constraint_container[name, t] = JuMP.@constraint(
                            container.JuMPmodel,
                            psi_variable_container[name, t] == pm_expr
                        )
                    end
                end
            end
        end
    end
end


text:
__precompile__(true)
module NNFEM
using PyPlot
using JLD2
using MAT
using PyCall
using Statistics
using LinearAlgebra
using ADCME
using SparseArrays
using ForwardDiff
using Random

animation = PyNULL()
colors = PyNULL()
cmx = PyNULL()
clb = PyNULL()

cpp_fint = nothing
sym_op = nothing
orthotropic_op = nothing
spd_op = nothing
chol_op = nothing
chol_orth_op = nothing
function __init__()
    global jet, cpp_fint, orthotropic_op, sym_op, spd_op, chol_op, chol_orth_op
    copy!(animation, pyimport("matplotlib.animation"))
    copy!(colors, pyimport("matplotlib.colors"))
    copy!(cmx, pyimport("matplotlib.cm"))
    jet = plt.get_cmap("jet")
    copy!(clb, pyimport("matplotlib.colorbar"))
    cpp_fint = load_op_and_grad("$(@__DIR__)/../deps/CustomOp/FintComp/build/libFintComp", "fint_comp")
    # sym_op = load_op_and_grad("$(@__DIR__)/../deps/CustomOp/SymOp/build/libSymOp", "sym_op")
    # orthotropic_op = load_op_and_grad("$(@__DIR__)/../deps/CustomOp/OrthotropicOp/build/libOrthotropicOp", "orthotropic_op")
    spd_op = load_op_and_grad("$(@__DIR__)/../deps/CustomOp/SPDOp/build/libSPDOp", "spd_op")
    #chol_op = load_op_and_grad("$(@__DIR__)/../deps/CustomOp/CholOp/build/libCholOp", "chol_op")
    chol_orth_op = load_op_and_grad("$(@__DIR__)/../deps/CustomOp/CholOrthOp/build/libCholOrthOp", "chol_orth_op")
end

include("utils/shapeFunctions.jl")
include("utils/matrix.jl")
include("materials/PlaneStress.jl")
include("materials/PlaneStrain.jl")
include("materials/PlaneStressPlasticity.jl")
include("materials/Elasticity1D.jl")
include("materials/Plasticity1D.jl")
include("materials/Viscoplasticity1D.jl")
include("materials/NeuralNetwork2D.jl")
include("materials/NeuralNetwork1D.jl")
include("materials/PathDependent1D.jl")
include("materials/PlaneStressPlasticityLawBased.jl")
include("materials/PlaneStressIncompressibleRivlinSaunders.jl")
include("solvers/Solvers.jl")
include("elements/FiniteStrainContinuum.jl")
include("elements/SmallStrainContinuum.jl")
include("elements/FiniteStrainTruss.jl")
include("fem/fem.jl")
include("fem/assembly.jl")
include("utils/Visualize.jl")
include("utils/io.jl")
include("utils/Testsuit.jl")
include("utils/nnconstitutivelaw.jl")
include("utils/linearConstitutiveLaw.jl")
include("solvers/NNSolver.jl")
include("solvers/AdjointSolver.jl")

end


text:
# Ilija Spasić PR 34-2020

"""
    generateArray(a,b,n=30)

Funkcija za generisanje zadatog niza brojeva iz opsega **[1 ... 100]**,
sa najmanje 30 elementa. Gde parametar **a** predstavlja početak opsega, parametar **b** kraj
opsega, dok je parametar **n** opcioni parametar za broj elemenata generisanog niza.
"""
function generateArray(a::Int64, b::Int64, n::Int64=30)::Array{Int64}
    if a < 1 || b > 100
        error("Neispravan opseg funkcije. Za vise informacija upisite ?generateArray")
    end
    X = [ ]
    for _ in 1:n
        push!(X, Int64(rand(a:b)))
    end
    return X
end

"""

    bucketSort(X::Array, smer::String)

Funkcija sortiranja niza primenom Bucket Sort algoritma. Gde smer uzima vrednosti
**"o"** za sortiranje u opadajućem poretku i
**"r"** za sortiranje u rastućem poretku
"""
function bucketSort(X::Array{Int64},smer::String="r")
    if smer != "r" && smer != "o"
        error("Pogrešan parametar funkcije! Proverite ? bucketSort")
    end
    rez = [ ]
    M = maximum(X)
    n = M/length(X)
    buckets = [ ]
    for _ in 1:length(X)
        push!(buckets,[ ])
    end
    for i in 1:length(X)
        j = Int64(floor((X[i]/n)))
        j = j == 0 ? 1 : j
        if j != length(X)
            push!(buckets[j],X[i])
        else
            push!(buckets[length(X)-1],X[i])
        end
    end
    for i in 1:length(X)
        insertSortBucket(buckets[i],smer)
    end
    if smer == "o"
        for i in 1:length(X)
            rez = vcat(buckets[i],rez)
        end
    else
        for i in 1:length(X)
            rez = vcat(rez,buckets[i])
        end
    end
    return rez
end

"""

    insertSortBucket(x::Array)

Pomoćna funkcija za sortiranja podeljenih delova (bucket-a) kod
Bucket Sort algoritma koja koristi Insertion Sort algoritam.
"""
function insertSortBucket(x,smer)
    for j in 2:length(x)
        key = x[j]
        i = j-1
        while i>0 && (smer == "o" ? x[i] < key : x[i] > key)
            x[i+1] = x[i]
            i = i-1
        end
        x[i+1] = key
    end
end