text:
# -*- coding: utf-8 -*-
# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .jl
#       format_name: light
#       format_version: '1.3'
#       jupytext_version: 0.8.6
#   kernelspec:
#     display_name: Julia 1.0.3
#     language: julia
#     name: julia-1.0
# ---

module NHostsMVectors
# # Model Specifications

# ## Host Specifications
#
# The host may be in one of 4 states:
#
# - susceptible (S_H)
#
# - incubation period (E_H)
#
# - infectious (I_H)
#
# - recovered (R_H)
#
# ## Vector Specifications
#
# The vector may be in one of 3 states:
#
# - susceptible (S_V)
#
# - incubation period (E_V)
#
# - infectious (I_V)

# # Model Parameters
#
# σ_H, σ_V: the incubation rates for hosts & vectors (units: per time)
#
# μ_H, μ_V: the mortality rates for hosts & vectors (units: per time)
#
# λ: the clearance (or recovery) rate for hosts (units: per time)
#
# β: the infection rate (units: per capita per time)

# $$N_H^i = S_H^i + E_H^i + I_H^i + R_H^i, \dot{N_H^i}=0$$
# $$N_H = \sum_{i=1}^N N_H^i$$
# $$\dot{S_H}^i = \mu_H^i(E_H^i + I_H^i + R_H^i) - \frac{\sum_{j=1}^M\beta^{ij}I_V^j}{N_H} S_H^i$$
# $$\dot{E_H}^i = \frac{\sum_{j=1}^M\beta^{ij}I_V^j}{N_H} S_H^i - (\sigma_H^i + \mu_H^i) E_H^i$$
# $$\dot{I_H}^i = \sigma_H^i E_H^i - (\lambda^i + \mu_H^i) I_H^i$$
# $$\dot{R_H}^i = \lambda^i I_H^i - \mu_H^i R_H^i$$
# $$\dot{S_V}^j = \mu_V^j(E_V^j + I_V^j) - \frac{\sum_{i=1}^N\beta^{ij} I_H^i}{N_H} S_V^j$$
# $$\dot{E_V}^j = \frac{\sum_{i=1}^N\beta^{ij} I_H^i}{N_H} S_V^j - (\sigma_V^j + \mu_V^j) E_V^j$$
# $$\dot{I_V}^j = \sigma_V^j E_V^j - \mu_V^j I_V^j$$

# This version considers multiple hosts, which introduces some indexing complications. This approach adopts the indexing scheme of:
#
# - all of host $i$ compartments ($S_H$, $E_H$, etc), for $i∈1…N$
# - vector compartments last
# With this approach, we can re-use the solution for one host, with slight modifications:

# This version considers multiple hosts and multiple vectors, which further complicates indexing. Now the indexing scheme is:
#
# all of host $i$ compartments ($S^{i}_H$, $E^{i}_H$, etc), for each $i∈1…N$
# all of vector $j$ compartments ($S^{j}_V$, $E^{j}_V$, etc), for each $j∈1…M$
# With this approach, we can again re-use the solutions for single host and single vector, with slight modifications:

# +
H_comps = 4
V_comps = 3

# in sub functions, du / u are the particular relevant slices only
function F1H(du, u, p, t, βslice, I_V, N_H)
    S_H, E_H, I_H, R_H = u

    # host dynamics
    host_infection = sum(βslice .* I_V)*S_H/N_H
    host_mortality = p.μ_H .* u # include S_H, so easier to remove mortality
    host_births = sum(host_mortality)
    host_progression = p.σ_H*E_H
    recovery = p.λ*I_H

    du[1] = -host_infection + host_births
    du[2] = host_infection - host_progression
    du[3] = host_progression - recovery
    du[4] = recovery
    du[1:end] -= host_mortality
end

# in sub functions, du / u are the particular relevant slices only
function F1V(du, u, p, t, βslice, I_H, N_H)
    S_V, E_V, I_V = u
    vec_infection = sum(βslice .* I_H)*S_V/N_H
    vec_mortality = p.μ_V .* u # include S_V, so easier to remove mortality
    vec_births = sum(vec_mortality)
    vec_progression = p.σ_V*E_V

    du[1] = -vec_infection + vec_births
    du[2] = vec_infection - vec_progression
    du[3] = vec_progression
    du[1:end] -= vec_mortality
end

function F(du,u,p,t)
    dH = @view(du[1:(p.nHosts*H_comps)])
    dV = @view(du[(p.nHosts*H_comps+1):end])
    Hs = @view(u[1:(p.nHosts*H_comps)])
    Vs = @view(u[(p.nHosts*H_comps+1):end])

    I_Vs = @view(Vs[3:V_comps:V_comps*p.nVecs])
    I_Hs = @view(Hs[3:H_comps:H_comps*p.nHosts])

    for host in 0:(p.nHosts-1)
        slice = (1:H_comps).+(H_comps*host)
        F1H(@view(dH[slice]), @view(Hs[slice]), p.host[host+1], t, @view(p.β[host+1,:]), I_Vs, p.N_H)
    end
    for vec in 0:(p.nVecs-1)
        slice = (1:V_comps).+(V_comps*vec)
        F1V(@view(dV[slice]), @view(Vs[slice]), p.vec[vec+1], t, @view(p.β[:,vec+1]), I_Hs, p.N_H)
    end
end
# -

# First, state initial conditions. This code generates them randomly for convenience, though they could be assigned based on data, desired parameter space, or algorithmically as part of a fitting process:

# +
using Random
nH = 2
nV = 2
Random.seed!(0)

S_Hs = ones(nH) .* 100.0
E_Hs = zeros(nH)
I_Hs = shuffle(vcat(zeros(nH-1),[1.0]))
R_Hs = zeros(nH)
host0 = reshape(hcat(S_Hs,E_Hs,I_Hs,R_Hs)', nH*H_comps, 1)

S_Vs = ones(nV) .* 1000.0
E_Vs = zeros(nV)
I_Vs = zeros(nV)
vec0 = reshape(hcat(S_Vs,E_Vs,I_Vs)', nV*V_comps, 1)

u0 = vcat(host0, vec0);
# -

# Now, generate dynamic parameters. Again: this code generates them randomly for convenience, though they could be assigned based on data, desired parameter space, or algorithmically as part of a fitting process:

# +
Random.seed!(1)

μs = 1 ./ (rand(nH) .* 360)
σs = 1 ./ (rand(nH) .* 6)
μVs = 1 ./ (rand(nV) .* 60)
σVs = 1 ./ (rand(nV) .* 14)

λs = 1 ./ (rand(nH) .* 28)
βs = rand(nH*nV) ./ 10.0

p = (
  nHosts = nH, nVecs = nV,
  N_H = sum(host0),
  β = reshape(βs,nH,nV), # information in hosts (rows) by vectors (cols)
  vec  = [(μ_V=μVs[j], σ_V=σVs[j]) for j in 1:nV],
  host = [(μ_H=μs[i], σ_H=σs[i], λ=λs[i]) for i in 1:nH]
  # just building up a random collection of params for demonstration
)
# -

# Now these values can be used with the ODE solver:

# +
using DifferentialEquations
using IterableTables, DataFrames

tspan = (0.0, 365.0)
prob = ODEProblem(F, u0, tspan, p)
sol = solve(prob,Tsit5(),reltol=1e-8,abstol=1e-8,saveat=range(0,365,length= 365*10+1));
# -

df = DataFrame(sol)
namespace = zip(names(df)[2:end],[
    :S_H1,:E_H1,:I_H1,:R_H1,
    :S_H2,:E_H2,:I_H2,:R_H2,
    :S_V1,:E_V1,:I_V1,
    :S_V2,:E_V2,:I_V2])
namespace = collect(namespace)
rename!(df,namespace);

using Plots
host_1 = plot(df[:timestamp],[df[:,:S_H1],df[:,:E_H1],df[:,:I_H1],df[:,:R_H1]])
host_2 = plot(df[:timestamp],[df[:,:S_H2],df[:,:E_H2],df[:,:I_H2],df[:,:R_H2]])
plot(host_1,host_2,layout=(2,1))

virus_1 = plot(df[:timestamp],[df[:,:S_V1],df[:,:E_V1],df[:,:I_V1]])
virus_2 = plot(df[:timestamp],[df[:,:S_V2],df[:,:E_V2],df[:,:I_V2]])
plot(virus_1,virus_2,layout=(2,1))

end


text:
using Match

function countletters()
end

function countletters(n)
	assert(0 <= n <= 1000)
	return @match n begin
		0 => length("")
   		1 => length("one")
   		2 => length("two")
   		3 => length("three")
   		4 => length("four")
   		5 => length("five")
   		6 => length("six")
	   	7 => length("seven")
   		8 => length("eight")
   		9 => length("nine")
   		10 => length("ten")
   		11 => length("eleven")
   		12 => length("twelve")
   		13 => length("thirteen")
   		14 => length("fourteen")
   		15 => length("fifteen")
   		16 => length("sixteen")
   		17 => length("seventeen")
   		18 => length("eighteen")
   		19 => length("nineteen")
		1000 => length("onethousand")
   		_    =>
   			if 20 <= n <= 29
   				length("twenty") + countletters(n%10)
   			elseif 30 <= n <= 39
   				length("thirty") + countletters(n%10)
   			elseif 40 <= n <= 49
   				length("forty") + countletters(n%10)
   			elseif 50 <= n <= 59
   				length("fifty") + countletters(n%10)
   			elseif 60 <= n <= 69
   				length("sixty") + countletters(n%10)
   			elseif 70 <= n <= 79
   				length("seventy") + countletters(n%10)
   			elseif 80 <= n <= 89
   				length("eighty") + countletters(n%10)
   			elseif 90 <= n <= 99
   				length("ninety") + countletters(n%10)
   			elseif 100 <= n <= 999
   				countletters(div(n,100)) + length("hundred") + ((n % 100) > 0 ? length("and") + countletters(n % 100) : 0)
   			end
	end
end

function main()
	assert(countletters(342) == 23) #"three hundred and forty two"
	assert(countletters(115) == 20) #"one hundred and fifteen"
	assert(sum(map(countletters,1:5)) == 19)
	assert(sum(map(countletters,1:9)) == 36)
	assert(sum(map(countletters,10:19)) == 70)
	assert(sum(map(countletters,20:99)) == 748)
	assert(sum(map(countletters,100:999)) == 20259)
	N = 1000
	s = sum(map(countletters,1:N))
	println(s)
end

main()

ext: jl

max_stars_repo_name: cmey/euler

max_issues_repo_name: cmey/euler

max_forks_repo_name: cmey/euler


text:
module QuickStructs

export CircularBuffer,
       RollingWindow,
       SLLNode,
       SinglyLinkedList,
       DLLNode,
       DoublyLinkedList,

       capacity,
       isfull,
       toarray,
       head,
       tail,
       peek,
       insertBefore!,
       insertAfter!,
       insertSorted!,
       moveToEnd!

# typealias IntIterable Union(Vector{Int}, StepRange{Int,Int}, UnitRange{Int})
typealias IntIterable AbstractVector{Int}

include("CircularBuffer.jl")
include("RollingWindow.jl")

include("SinglyLinkedList.jl")
include("DoublyLinkedList.jl")

end # module


text:
using Documenter, Hubbard

makedocs(sitename="Hubbard Model")

max_stars_repo_name: jburgy/hubbard

max_issues_repo_name: jburgy/hubbard

max_forks_repo_name: jburgy/hubbard


text:
export convcnp_1d

"""
    convcnp_1d(;
        receptive_field::Float32,
        num_layers::Integer,
        num_channels::Integer,
        points_per_unit::Float32,
        margin::Float32=receptive_field
    )

Construct a ConvCNP for one-dimensional data.

# Keywords
- `receptive_field::Float32`: Width of the receptive field.
- `num_layers::Integer`: Number of layers of the CNN, excluding an initial
    and final pointwise convolutional layer to change the number of channels
    appropriately.
- `num_channels::Integer`: Number of channels of the CNN.
- `points_per_unit::Float32`: Points per unit for the discretisation. See
    `UniformDiscretisation1D`.
- `margin::Float32=receptive_field`: Margin for the discretisation. See
    `UniformDiscretisation1D`.
"""
function convcnp_1d(;
    receptive_field::Float32,
    num_layers::Integer,
    num_channels::Integer,
    points_per_unit::Float32,
    margin::Float32=receptive_field
)
    dim_x = 1
    dim_y = 1
    scale = 2 / points_per_unit
    return Model(
        FunctionalCoder(
            UniformDiscretisation1D(points_per_unit, margin),
            Chain(
                set_conv(dim_y, scale; density=true),
                DeterministicLikelihood()
            )
        ),
        Chain(
            build_conv(
                receptive_field,
                num_layers,
                num_channels,
                points_per_unit =points_per_unit,
                dimensionality  =1,
                num_in_channels =dim_y + 1,  # Account for density channel.
                num_out_channels=2dim_y
            ),
            set_conv(2dim_y, scale),
            HeterogeneousGaussianLikelihood()
        )
    )
end


text:
export ft_ee_read, ft_ee_program
export FtProgramData
export FT_232R_CBUS_TXDEN, FT_232R_CBUS_PWRON, FT_232R_CBUS_RXLED,
       FT_232R_CBUS_TXLED, FT_232R_CBUS_TXRXLED, FT_232R_CBUS_SLEEP,
       FT_232R_CBUS_CLK48, FT_232R_CBUS_CLK24, FT_232R_CBUS_CLK12,
       FT_232R_CBUS_CLK6, FT_232R_CBUS_IOMODE, FT_232R_CBUS_BITBANG_WR,
       FT_232R_CBUS_BITBANG_RD
export FT_232H_CBUS_TRISTATE, FT_232H_CBUS_RXLED, FT_232H_CBUS_TXLED,
       FT_232H_CBUS_TXRXLED, FT_232H_CBUS_PWREN, FT_232H_CBUS_SLEEP,
       FT_232H_CBUS_DRIVE_0, FT_232H_CBUS_DRIVE_1, FT_232H_CBUS_IOMODE,
       FT_232H_CBUS_TXDEN, FT_232H_CBUS_CLK30, FT_232H_CBUS_CLK15,
       FT_232H_CBUS_CLK7_5
export FT_X_SERIES_CBUS_TRISTATE, FT_X_SERIES_CBUS_RXLED, FT_X_SERIES_CBUS_TXLED,
       FT_X_SERIES_CBUS_TXRXLED, FT_X_SERIES_CBUS_PWREN, FT_X_SERIES_CBUS_SLEEP,
       FT_X_SERIES_CBUS_DRIVE_0, FT_X_SERIES_CBUS_DRIVE_1, FT_X_SERIES_CBUS_IOMODE,
       FT_X_SERIES_CBUS_TXDEN, FT_X_SERIES_CBUS_CLK24, FT_X_SERIES_CBUS_CLK12,
       FT_X_SERIES_CBUS_CLK6, FT_X_SERIES_CBUS_BCD_CHARGER, FT_X_SERIES_CBUS_BCD_CHARGER_N,
       FT_X_SERIES_CBUS_I2C_TXE, FT_X_SERIES_CBUS_I2C_RXF, FT_X_SERIES_CBUS_VBUS_SENSE,
       FT_X_SERIES_CBUS_BITBANG_WR, FT_X_SERIES_CBUS_BITBANG_RD, FT_X_SERIES_CBUS_TIMESTAMP,
       FT_X_SERIES_CBUS_KEEP_AWAKE
export FT_DRIVER_TYPE_D2XX, FT_DRIVER_TYPE_VCP

#FT232R CBUS EEPROM OPTIONS - Ignored for FT245R (see ft_ee_program and ft_ee_read)
const FT_232R_CBUS_TXDEN = 0x00
const FT_232R_CBUS_PWRON = 0x01
const FT_232R_CBUS_RXLED = 0x02
const FT_232R_CBUS_TXLED = 0x03
const FT_232R_CBUS_TXRXLED = 0x04
const FT_232R_CBUS_SLEEP = 0x05
const FT_232R_CBUS_CLK48 = 0x06
const FT_232R_CBUS_CLK24 = 0x07
const FT_232R_CBUS_CLK12 = 0x08
const FT_232R_CBUS_CLK6 = 0x09
const FT_232R_CBUS_IOMODE = 0x0A
const FT_232R_CBUS_BITBANG_WR = 0x0B
const FT_232R_CBUS_BITBANG_RD = 0x0C

#FT232H CBUS EEPROM OPTIONS (see ft_ee_program and ft_ee_read)
const FT_232H_CBUS_TRISTATE = 0x00
const FT_232H_CBUS_RXLED = 0x01
const FT_232H_CBUS_TXLED = 0x02
const FT_232H_CBUS_TXRXLED = 0x03
const FT_232H_CBUS_PWREN = 0x04
const FT_232H_CBUS_SLEEP = 0x05
const FT_232H_CBUS_DRIVE_0 = 0x06
const FT_232H_CBUS_DRIVE_1 = 0x07
const FT_232H_CBUS_IOMODE = 0x08
const FT_232H_CBUS_TXDEN = 0x09
const FT_232H_CBUS_CLK30 = 0x0A
const FT_232H_CBUS_CLK15 = 0x0B
const FT_232H_CBUS_CLK7_5 = 0x0C

#FT X Series CBUS Options EEPROM values (see ft_eeprom_read and ft_eeprom_program)
const FT_X_SERIES_CBUS_TRISTATE = 0x00
const FT_X_SERIES_CBUS_RXLED = 0x01
const FT_X_SERIES_CBUS_TXLED = 0x02
const FT_X_SERIES_CBUS_TXRXLED = 0x03
const FT_X_SERIES_CBUS_PWREN = 0x04
const FT_X_SERIES_CBUS_SLEEP = 0x05
const FT_X_SERIES_CBUS_DRIVE_0 = 0x06
const FT_X_SERIES_CBUS_DRIVE_1 = 0x07
const FT_X_SERIES_CBUS_IOMODE = 0x08
const FT_X_SERIES_CBUS_TXDEN = 0x09
const FT_X_SERIES_CBUS_CLK24 = 0x0A
const FT_X_SERIES_CBUS_CLK12 = 0x0B
const FT_X_SERIES_CBUS_CLK6 = 0x0C
const FT_X_SERIES_CBUS_BCD_CHARGER = 0x0D
const FT_X_SERIES_CBUS_BCD_CHARGER_N = 0x0E
const FT_X_SERIES_CBUS_I2C_TXE = 0x0F
const FT_X_SERIES_CBUS_I2C_RXF = 0x10
const FT_X_SERIES_CBUS_VBUS_SENSE = 0x11
const FT_X_SERIES_CBUS_BITBANG_WR = 0x12
const FT_X_SERIES_CBUS_BITBANG_RD = 0x13
const FT_X_SERIES_CBUS_TIMESTAMP = 0x14
const FT_X_SERIES_CBUS_KEEP_AWAKE = 0x15

# Driver types
const FT_DRIVER_TYPE_D2XX = 0
const FT_DRIVER_TYPE_VCP = 1

# FT_PROGRAM_DATA_STRUCTURE
type FtProgramData_C
  Signature1 :: Cuint # Header - must be 0x0000000
  Signature2 :: Cuint # Header - must be 0xffffffff
  Version :: Cuint # Header - FT_PROGRAM_DATA version
                   # 0 = original (FT232B)
                   # 1 = FT2232 extensions
                   # 2 = FT232R extensions
                   # 3 = FT2232H extensions
                   # 4 = FT4232H extensions
                   # 5 = FT232H extensions
  VendorId :: Cushort # 0x0403
  ProductId :: Cushort # 0x6001
  Manufacturer :: Ptr{UInt8}    # "FTDI"
  ManufacturerId :: Ptr{UInt8} # "FT"
  Description :: Ptr{UInt8}    # "USB HS Serial Converter"
  SerialNumber :: Ptr{UInt8}   # "FT000001" if fixed, or NULL
  MaxPower :: Cushort # 0 < MaxPower <= 500
  PnP :: Cushort # 0 = disabled, 1 = enabled
  SelfPowered :: Cushort # 0 = bus powered, 1 = self powered
  RemoteWakeup :: Cushort  # 0 = not capable, 1 = capable
  #
  # Rev4 (FT232B) extensions
  #
  Rev4 :: Cuchar # non-zero if Rev4 chip, zero otherwise
  IsoIn :: Cuchar # non-zero if in endpoint is isochronous
  IsoOut :: Cuchar # non-zero if out endpoint is isochronous
  PullDownEnable :: Cuchar # non-zero if pull down enabled
  SerNumEnable :: Cuchar # non-zero if serial number to be used
  USBVersionEnable :: Cuchar # non-zero if chip uses USBVersion
  USBVersion :: Cushort # BCD (0x0200 => USB2)
  #
  # Rev 5 (FT2232) extensions
  #
  Rev5 :: Cuchar # non-zero if Rev5 chip, zero otherwise
  IsoInA :: Cuchar # non-zero if in endpoint is isochronous
  IsoInB :: Cuchar # non-zero if in endpoint is isochronous
  IsoOutA :: Cuchar # non-zero if out endpoint is isochronous
  IsoOutB :: Cuchar # non-zero if out endpoint is isochronous
  PullDownEnable5 :: Cuchar # non-zero if pull down enabled
  SerNumEnable5 :: Cuchar # non-zero if serial number to be used
  USBVersionEnable5 :: Cuchar # non-zero if chip uses USBVersion
  USBVersion5 :: Cshort # BCD (0x0200 => USB2)
  AIsHighCurrent :: Cuchar # non-zero if interface is high current
  BIsHighCurrent :: Cuchar # non-zero if interface is high current
  IFAIsFifo :: Cuchar # non-zero if interface is 245 FIFO
  IFAIsFifoTar :: Cuchar # non-zero if interface is 245 FIFO CPU target
  IFAIsFastSer :: Cuchar # non-zero if interface is Fast serial
  AIsVCP :: Cuchar # non-zero if interface is to use VCP drivers
  IFBIsFifo :: Cuchar # non-zero if interface is 245 FIFO
  IFBIsFifoTar :: Cuchar # non-zero if interface is 245 FIFO CPU target
  IFBIsFastSer :: Cuchar # non-zero if interface is Fast serial
  BIsVCP  :: Cuchar # non-zero if interface is to use VCP drivers
  #
  # Rev 6 (FT232R) extensions
  #
  UseExtOsc :: Cuchar # Use External Oscillator
  HighDriveIOs :: Cuchar # High Drive I/Os
  EndpointSize :: Cuchar # Endpoint size
  PullDownEnableR :: Cuchar # non-zero if pull down enabled
  SerNumEnableR :: Cuchar # non-zero if serial number to be used
  InvertTXD :: Cuchar # non-zero if invert TXD
  InvertRXD :: Cuchar # non-zero if invert RXD
  InvertRTS :: Cuchar # non-zero if invert RTS
  InvertCTS :: Cuchar # non-zero if invert CTS
  InvertDTR :: Cuchar # non-zero if invert DTR
  InvertDSR :: Cuchar # non-zero if invert DSR
  InvertDCD :: Cuchar # non-zero if invert DCD
  InvertRI  :: Cuchar # non-zero if invert RI
  Cbus0 :: Cuchar # Cbus Mux control
  Cbus1 :: Cuchar # Cbus Mux control
  Cbus2 :: Cuchar # Cbus Mux control
  Cbus3 :: Cuchar # Cbus Mux control
  Cbus4 :: Cuchar # Cbus Mux control
  RIsD2XX :: Cuchar # non-zero if using D2XX driver
  #
  # Rev 7 (FT2232H) Extensions
  #
  PullDownEnable7 :: Cuchar # non-zero if pull down enabled
  SerNumEnable7 :: Cuchar # non-zero if serial number to be used
  ALSlowSlew :: Cuchar # non-zero if AL pins have slow slew
  ALSchmittInput :: Cuchar # non-zero if AL pins are Schmitt input
  ALDriveCurrent :: Cuchar # valid values are 4mA, 8mA, 12mA, 16mA
  AHSlowSlew :: Cuchar # non-zero if AH pins have slow slew
  AHSchmittInput :: Cuchar # non-zero if AH pins are Schmitt input
  AHDriveCurrent :: Cuchar # valid values are 4mA, 8mA, 12mA, 16mA
  BLSlowSlew :: Cuchar # non-zero if BL pins have slow slew
  BLSchmittInput :: Cuchar # non-zero if BL pins are Schmitt input
  BLDriveCurrent :: Cuchar # valid values are 4mA, 8mA, 12mA, 16mA
  BHSlowSlew :: Cuchar # non-zero if BH pins have slow slew
  BHSchmittInput :: Cuchar # non-zero if BH pins are Schmitt input
  BHDriveCurrent :: Cuchar # valid values are 4mA, 8mA, 12mA, 16mA
  IFAIsFifo7 :: Cuchar # non-zero if interface is 245 FIFO
  IFAIsFifoTar7 :: Cuchar # non-zero if interface is 245 FIFO CPU target
  IFAIsFastSer7 :: Cuchar # non-zero if interface is Fast serial
  AIsVCP7 :: Cuchar # non-zero if interface is to use VCP drivers
  IFBIsFifo7 :: Cuchar # non-zero if interface is 245 FIFO
  IFBIsFifoTar7 :: Cuchar # non-zero if interface is 245 FIFO CPU target
  IFBIsFastSer7 :: Cuchar # non-zero if interface is Fast serial
  BIsVCP7 :: Cuchar # non-zero if interface is to use VCP drivers
  PowerSaveEnable :: Cuchar # non-zero if using BCBUS7 to save power for self-powered designs
  #
  # Rev 8 (FT4232H) Extensions
  #
  PullDownEnable8 :: Cuchar # non-zero if pull down enabled
  SerNumEnable8 :: Cuchar # non-zero if serial number to be used
  ASlowSlew :: Cuchar # non-zero if AL pins have slow slew
  ASchmittInput :: Cuchar # non-zero if AL pins are Schmitt input
  ADriveCurrent :: Cuchar # valid values are 4mA, 8mA, 12mA, 16mA
  BSlowSlew :: Cuchar # non-zero if AH pins have slow slew
  BSchmittInput :: Cuchar # non-zero if AH pins are Schmitt input
  BDriveCurrent :: Cuchar # valid values are 4mA, 8mA, 12mA, 16mA
  CSlowSlew :: Cuchar # non-zero if BL pins have slow slew
  CSchmittInput :: Cuchar # non-zero if BL pins are Schmitt input
  CDriveCurrent :: Cuchar # valid values are 4mA, 8mA, 12mA, 16mA
  DSlowSlew :: Cuchar # non-zero if BH pins have slow slew
  DSchmittInput :: Cuchar # non-zero if BH pins are Schmitt input
  DDriveCurrent :: Cuchar # valid values are 4mA, 8mA, 12mA, 16mA
  ARIIsTXDEN :: Cuchar # non-zero if port A uses RI as RS485 TXDEN
  BRIIsTXDEN :: Cuchar # non-zero if port B uses RI as RS485 TXDEN
  CRIIsTXDEN :: Cuchar # non-zero if port C uses RI as RS485 TXDEN
  DRIIsTXDEN :: Cuchar # non-zero if port D uses RI as RS485 TXDEN
  AIsVCP8 :: Cuchar # non-zero if interface is to use VCP drivers
  BIsVCP8 :: Cuchar # non-zero if interface is to use VCP drivers
  CIsVCP8 :: Cuchar # non-zero if interface is to use VCP drivers
  DIsVCP8 :: Cuchar # non-zero if interface is to use VCP drivers
  #
  # Rev 9 (FT232H) Extensions
  #
  PullDownEnableH :: Cuchar # non-zero if pull down enabled
  SerNumEnableH :: Cuchar # non-zero if serial number to be used
  ACSlowSlewH :: Cuchar # non-zero if AC pins have slow slew
  ACSchmittInputH :: Cuchar # non-zero if AC pins are Schmitt input
  ACDriveCurrentH :: Cuchar # valid values are 4mA, 8mA, 12mA, 16mA
  ADSlowSlewH :: Cuchar # non-zero if AD pins have slow slew
  ADSchmittInputH :: Cuchar # non-zero if AD pins are Schmitt input
  ADDriveCurrentH :: Cuchar # valid values are 4mA, 8mA, 12mA, 16mA
  Cbus0H :: Cuchar # Cbus Mux control
  Cbus1H :: Cuchar # Cbus Mux control
  Cbus2H :: Cuchar # Cbus Mux control
  Cbus3H :: Cuchar # Cbus Mux control
  Cbus4H :: Cuchar # Cbus Mux control
  Cbus5H :: Cuchar # Cbus Mux control
  Cbus6H :: Cuchar # Cbus Mux control
  Cbus7H :: Cuchar # Cbus Mux control
  Cbus8H :: Cuchar # Cbus Mux control
  Cbus9H :: Cuchar # Cbus Mux control
  IsFifoH :: Cuchar # non-zero if interface is 245 FIFO
  IsFifoTarH :: Cuchar # non-zero if interface is 245 FIFO CPU target
  IsFastSerH :: Cuchar # non-zero if interface is Fast serial
  IsFT1248H :: Cuchar # non-zero if interface is FT1248
  FT1248CpolH :: Cuchar # FT1248 clock polarity - clock idle high (1) or clock idle low (0)
  FT1248LsbH :: Cuchar # FT1248 data is LSB (1) or MSB (0)
  FT1248FlowControlH :: Cuchar # FT1248 flow control enable
  IsVCPH :: Cuchar # non-zero if interface is to use VCP drivers
  PowerSaveEnableH :: Cuchar # non-zero if using ACBUS7 to save power for self-powered designs

  function FtProgramData_C(Version::Integer,
                           Manufacturer::ASCIIString,
                           ManufacturerId::ASCIIString,
                           Description::ASCIIString,
                           SerialNumber::ASCIIString)
    @assert (length(Manufacturer) + length(ManufacturerId)) < 41
    @assert length(Description)<=64
    @assert length(SerialNumber)<=16
    mfg = zeros(UInt8,41)
    mfgid = zeros(UInt8,41)
    d = zeros(UInt8,65)
    sn = zeros(UInt8,17)
    for (p,c) in enumerate(Manufacturer)
      mfg[p] = Int(c)
    end
    for (p,c) in enumerate(ManufacturerId)
      mfgid[p] = Int(c)
    end
    for (p,c) in enumerate(Description)
      d[p] = Int(c)
    end
    for (p,c) in enumerate(SerialNumber)
      sn[p] = Int(c)
    end
    mfgptr = pointer(mfg)
    mfgidptr = pointer(mfgid)
    dptr = pointer(d)
    snptr = pointer(sn)
    new(0x00000000, 0xffffffff, Version, 0, 0, mfgptr, mfgidptr, dptr, snptr)
  end
  FtProgramData_C(Version) = FtProgramData_C(Version,"","","","")
end

type FtProgramData
  Signature1 :: UInt32 # Header - must be 0x0000000
  Signature2 :: UInt32 # Header - must be 0xffffffff
  Version :: UInt32 # Header - FT_PROGRAM_DATA version
                   # 0 = original (FT232B)
                   # 1 = FT2232 extensions
                   # 2 = FT232R extensions
                   # 3 = FT2232H extensions
                   # 4 = FT4232H extensions
                   # 5 = FT232H extensions
  VendorId :: UInt16 # 0x0403
  ProductId :: UInt16 # 0x6001
  Manufacturer :: ASCIIString     # "FTDI"
  ManufacturerId :: ASCIIString  # "FT"
  Description :: ASCIIString     # "USB HS Serial Converter"
  SerialNumber :: ASCIIString    # "FT000001" if fixed, or NULL
  MaxPower :: UInt16 # 0 < MaxPower <= 500
  PnP :: UInt16 # 0 = disabled, 1 = enabled
  SelfPowered :: UInt16 # 0 = bus powered, 1 = self powered
  RemoteWakeup :: UInt16  # 0 = not capable, 1 = capable
  #
  # Rev4 (FT232B) extensions
  #
  Rev4 :: UInt8 # non-zero if Rev4 chip, zero otherwise
  IsoIn :: UInt8 # non-zero if in endpoint is isochronous
  IsoOut :: UInt8 # non-zero if out endpoint is isochronous
  PullDownEnable :: UInt8 # non-zero if pull down enabled
  SerNumEnable :: UInt8 # non-zero if serial number to be used
  USBVersionEnable :: UInt8 # non-zero if chip uses USBVersion
  USBVersion :: UInt16 # BCD (0x0200 => USB2)
  #
  # Rev 5 (FT2232) extensions
  #
  Rev5 :: UInt8 # non-zero if Rev5 chip, zero otherwise
  IsoInA :: UInt8 # non-zero if in endpoint is isochronous
  IsoInB :: UInt8 # non-zero if in endpoint is isochronous
  IsoOutA :: UInt8 # non-zero if out endpoint is isochronous
  IsoOutB :: UInt8 # non-zero if out endpoint is isochronous
  PullDownEnable5 :: UInt8 # non-zero if pull down enabled
  SerNumEnable5 :: UInt8 # non-zero if serial number to be used
  USBVersionEnable5 :: UInt8 # non-zero if chip uses USBVersion
  USBVersion5 :: UInt16 # BCD (0x0200 => USB2)
  AIsHighCurrent :: UInt8 # non-zero if interface is high current
  BIsHighCurrent :: UInt8 # non-zero if interface is high current
  IFAIsFifo :: UInt8 # non-zero if interface is 245 FIFO
  IFAIsFifoTar :: UInt8 # non-zero if interface is 245 FIFO CPU target
  IFAIsFastSer :: UInt8 # non-zero if interface is Fast serial
  AIsVCP :: UInt8 # non-zero if interface is to use VCP drivers
  IFBIsFifo :: UInt8 # non-zero if interface is 245 FIFO
  IFBIsFifoTar :: UInt8 # non-zero if interface is 245 FIFO CPU target
  IFBIsFastSer :: UInt8 # non-zero if interface is Fast serial
  BIsVCP  :: UInt8 # non-zero if interface is to use VCP drivers
  #
  # Rev 6 (FT232R) extensions
  #
  UseExtOsc :: UInt8 # Use External Oscillator
  HighDriveIOs :: UInt8 # High Drive I/Os
  EndpointSize :: UInt8 # Endpoint size
  PullDownEnableR :: UInt8 # non-zero if pull down enabled
  SerNumEnableR :: UInt8 # non-zero if serial number to be used
  InvertTXD :: UInt8 # non-zero if invert TXD
  InvertRXD :: UInt8 # non-zero if invert RXD
  InvertRTS :: UInt8 # non-zero if invert RTS
  InvertCTS :: UInt8 # non-zero if invert CTS
  InvertDTR :: UInt8 # non-zero if invert DTR
  InvertDSR :: UInt8 # non-zero if invert DSR
  InvertDCD :: UInt8 # non-zero if invert DCD
  InvertRI  :: UInt8 # non-zero if invert RI
  Cbus0 :: UInt8 # Cbus Mux control
  Cbus1 :: UInt8 # Cbus Mux control
  Cbus2 :: UInt8 # Cbus Mux control
  Cbus3 :: UInt8 # Cbus Mux control
  Cbus4 :: UInt8 # Cbus Mux control
  RIsD2XX :: UInt8 # non-zero if using D2XX driver
  #
  # Rev 7 (FT2232H) Extensions
  #
  PullDownEnable7 :: UInt8 # non-zero if pull down enabled
  SerNumEnable7 :: UInt8 # non-zero if serial number to be used
  ALSlowSlew :: UInt8 # non-zero if AL pins have slow slew
  ALSchmittInput :: UInt8 # non-zero if AL pins are Schmitt input
  ALDriveCurrent :: UInt8 # valid values are 4mA, 8mA, 12mA, 16mA
  AHSlowSlew :: UInt8 # non-zero if AH pins have slow slew
  AHSchmittInput :: UInt8 # non-zero if AH pins are Schmitt input
  AHDriveCurrent :: UInt8 # valid values are 4mA, 8mA, 12mA, 16mA
  BLSlowSlew :: UInt8 # non-zero if BL pins have slow slew
  BLSchmittInput :: UInt8 # non-zero if BL pins are Schmitt input
  BLDriveCurrent :: UInt8 # valid values are 4mA, 8mA, 12mA, 16mA
  BHSlowSlew :: UInt8 # non-zero if BH pins have slow slew
  BHSchmittInput :: UInt8 # non-zero if BH pins are Schmitt input
  BHDriveCurrent :: UInt8 # valid values are 4mA, 8mA, 12mA, 16mA
  IFAIsFifo7 :: UInt8 # non-zero if interface is 245 FIFO
  IFAIsFifoTar7 :: UInt8 # non-zero if interface is 245 FIFO CPU target
  IFAIsFastSer7 :: UInt8 # non-zero if interface is Fast serial
  AIsVCP7 :: UInt8 # non-zero if interface is to use VCP drivers
  IFBIsFifo7 :: UInt8 # non-zero if interface is 245 FIFO
  IFBIsFifoTar7 :: UInt8 # non-zero if interface is 245 FIFO CPU target
  IFBIsFastSer7 :: UInt8 # non-zero if interface is Fast serial
  BIsVCP7 :: UInt8 # non-zero if interface is to use VCP drivers
  PowerSaveEnable :: UInt8 # non-zero if using BCBUS7 to save power for self-powered designs
  #
  # Rev 8 (FT4232H) Extensions
  #
  PullDownEnable8 :: UInt8 # non-zero if pull down enabled
  SerNumEnable8 :: UInt8 # non-zero if serial number to be used
  ASlowSlew :: UInt8 # non-zero if AL pins have slow slew
  ASchmittInput :: UInt8 # non-zero if AL pins are Schmitt input
  ADriveCurrent :: UInt8 # valid values are 4mA, 8mA, 12mA, 16mA
  BSlowSlew :: UInt8 # non-zero if AH pins have slow slew
  BSchmittInput :: UInt8 # non-zero if AH pins are Schmitt input
  BDriveCurrent :: UInt8 # valid values are 4mA, 8mA, 12mA, 16mA
  CSlowSlew :: UInt8 # non-zero if BL pins have slow slew
  CSchmittInput :: UInt8 # non-zero if BL pins are Schmitt input
  CDriveCurrent :: UInt8 # valid values are 4mA, 8mA, 12mA, 16mA
  DSlowSlew :: UInt8 # non-zero if BH pins have slow slew
  DSchmittInput :: UInt8 # non-zero if BH pins are Schmitt input
  DDriveCurrent :: UInt8 # valid values are 4mA, 8mA, 12mA, 16mA
  ARIIsTXDEN :: UInt8 # non-zero if port A uses RI as RS485 TXDEN
  BRIIsTXDEN :: UInt8 # non-zero if port B uses RI as RS485 TXDEN
  CRIIsTXDEN :: UInt8 # non-zero if port C uses RI as RS485 TXDEN
  DRIIsTXDEN :: UInt8 # non-zero if port D uses RI as RS485 TXDEN
  AIsVCP8 :: UInt8 # non-zero if interface is to use VCP drivers
  BIsVCP8 :: UInt8 # non-zero if interface is to use VCP drivers
  CIsVCP8 :: UInt8 # non-zero if interface is to use VCP drivers
  DIsVCP8 :: UInt8 # non-zero if interface is to use VCP drivers
  #
  # Rev 9 (FT232H) Extensions
  #
  PullDownEnableH :: UInt8 # non-zero if pull down enabled
  SerNumEnableH :: UInt8 # non-zero if serial number to be used
  ACSlowSlewH :: UInt8 # non-zero if AC pins have slow slew
  ACSchmittInputH :: UInt8 # non-zero if AC pins are Schmitt input
  ACDriveCurrentH :: UInt8 # valid values are 4mA, 8mA, 12mA, 16mA
  ADSlowSlewH :: UInt8 # non-zero if AD pins have slow slew
  ADSchmittInputH :: UInt8 # non-zero if AD pins are Schmitt input
  ADDriveCurrentH :: UInt8 # valid values are 4mA, 8mA, 12mA, 16mA
  Cbus0H :: UInt8 # Cbus Mux control
  Cbus1H :: UInt8 # Cbus Mux control
  Cbus2H :: UInt8 # Cbus Mux control
  Cbus3H :: UInt8 # Cbus Mux control
  Cbus4H :: UInt8 # Cbus Mux control
  Cbus5H :: UInt8 # Cbus Mux control
  Cbus6H :: UInt8 # Cbus Mux control
  Cbus7H :: UInt8 # Cbus Mux control
  Cbus8H :: UInt8 # Cbus Mux control
  Cbus9H :: UInt8 # Cbus Mux control
  IsFifoH :: UInt8 # non-zero if interface is 245 FIFO
  IsFifoTarH :: UInt8 # non-zero if interface is 245 FIFO CPU target
  IsFastSerH :: UInt8 # non-zero if interface is Fast serial
  IsFT1248H :: UInt8 # non-zero if interface is FT1248
  FT1248CpolH :: UInt8 # FT1248 clock polarity - clock idle high (1) or clock idle low (0)
  FT1248LsbH :: UInt8 # FT1248 data is LSB (1) or MSB (0)
  FT1248FlowControlH :: UInt8 # FT1248 flow control enable
  IsVCPH :: UInt8 # non-zero if interface is to use VCP drivers
  PowerSaveEnableH :: UInt8 # non-zero if using ACBUS7 to save power for self-powered designs
  function FtProgramData(pd :: FtProgramData_C)
    newpd = new(pd.Signature1,pd.Signature2,pd.Version,pd.VendorId,pd.ProductId)
    newpd.Manufacturer = bytestring(pd.Manufacturer)
    newpd.ManufacturerId = bytestring(pd.ManufacturerId)
    newpd.Description = bytestring(pd.Description)
    newpd.SerialNumber = bytestring(pd.SerialNumber)
    for i in 10:130
      newpd.(i) = pd.(i)
    end
    return newpd
  end
end

function FtProgramData_C(pd::FtProgramData)
  newpd = FtProgramData_C(pd.Version,pd.Manufacturer,pd.ManufacturerId,pd.Description,pd.SerialNumber)
  newpd.VendorId = pd.VendorId
  newpd.ProductId = pd.ProductId
  for i in 10:130
    newpd.(i) = pd.(i)
  end
  return newpd
end

function Base.show(io::IO, pd::FtProgramData)
  f()=@printf(io,"Signature1 = 0x%08x \n",pd.Signature1);f()
  f()=@printf(io,"Signature2 = 0x%08x \n",pd.Signature2);f()
  f()=@printf(io,"Version = 0x%08x \n",pd.Version);f()
  f()=@printf(io,"VendorId = 0x%04x \n",pd.VendorId);f()
  f()=@printf(io,"ProductId = 0x%04x \n",pd.ProductId);f()
  println(io,"Manufacturer = $(pd.Manufacturer)")
  println(io,"ManufacturerId = $(pd.ManufacturerId)")
  println(io,"Description = $(pd.Description)")
  println(io,"SerialNumber = $(pd.SerialNumber)")
  f()=@printf(io,"MaxPower = 0x%04x \n",pd.MaxPower) ;f()
  f()=@printf(io,"PnP = 0x%04x \n",pd.PnP) ;f()
  f()=@printf(io,"SelfPowered = 0x%04x \n",pd.SelfPowered) ;f()
  f()=@printf(io,"RemoteWakeup = 0x%04x \n",pd.RemoteWakeup);f()
  if pd.Version >= 0
    println(io)
    println(io,"Rev4 (FT232B) extensions")
    f()=@printf(io,"Rev4 = 0x%02x \n",pd.Rev4);f()
    f()=@printf(io,"IsoIn = 0x%02x \n",pd.IsoIn);f()
    f()=@printf(io,"PullDownEnable = 0x%02x \n",pd.PullDownEnable);f()
    f()=@printf(io,"SerNumEnable = 0x%02x \n",pd.SerNumEnable);f()
    f()=@printf(io,"USBVersionEnable = 0x%02x \n",pd.USBVersionEnable);f()
    f()=@printf(io,"USBVersion = 0x%04x \n",pd.USBVersion);f()
  end
  if pd.Version >= 1
    println(io)
    println(io,"Rev 5 (FT2232) extensions")
    f()=@printf(io,"Rev5 = 0x%02x \n",pd.Rev5);f()
    f()=@printf(io,"IsoInA = 0x%02x \n",pd.IsoInA);f()
    f()=@printf(io,"IsoInB = 0x%02x \n",pd.IsoInB);f()
    f()=@printf(io,"IsoOutA = 0x%02x \n",pd.IsoOutA);f()
    f()=@printf(io,"PullDownEnable5 = 0x%02x \n",pd.PullDownEnable5);f()
    f()=@printf(io,"SerNumEnable5 = 0x%02x \n",pd.SerNumEnable5);f()
    f()=@printf(io,"USBVersionEnable5 = 0x%02x \n",pd.USBVersionEnable5);f()
    f()=@printf(io,"USBVersion5 = 0x%04x \n",pd.USBVersion5);f()
    f()=@printf(io,"AIsHighCurrent = 0x%02x \n",pd.AIsHighCurrent);f()
    f()=@printf(io,"BIsHighCurrent = 0x%02x \n",pd.BIsHighCurrent);f()
    f()=@printf(io,"IFAIsFifo = 0x%02x \n",pd.IFAIsFifo);f()
    f()=@printf(io,"IFAIsFifoTar = 0x%02x \n",pd.IFAIsFifoTar);f()
    f()=@printf(io,"IFAIsFastSer = 0x%02x \n",pd.IFAIsFastSer);f()
    f()=@printf(io,"AIsVCP = 0x%02x \n",pd.AIsVCP);f()
    f()=@printf(io,"IFBIsFifo = 0x%02x \n",pd.IFBIsFifo);f()
    f()=@printf(io,"IFBIsFifoTar = 0x%02x \n",pd.IFBIsFifoTar);f()
    f()=@printf(io,"IFBIsFastSer = 0x%02x \n",pd.IFBIsFastSer);f()
    f()=@printf(io,"BIsVCP = 0x%02x \n",pd.BIsVCP);f()
  end
  if pd.Version >=2
    println(io)
    println(io,"Rev 6 (FT232R) extensions")
    f()=@printf(io,"UseExtOsc = 0x%02x \n",pd.UseExtOsc);f()
    f()=@printf(io,"HighDriveIOs = 0x%02x \n",pd.HighDriveIOs);f()
    f()=@printf(io,"EndpointSize = 0x%02x \n",pd.EndpointSize);f()
    f()=@printf(io,"PullDownEnableR = 0x%02x \n",pd.PullDownEnableR);f()
    f()=@printf(io,"SerNumEnableR = 0x%02x \n",pd.SerNumEnableR);f()
    f()=@printf(io,"InvertTXD = 0x%02x \n",pd.InvertTXD);f()
    f()=@printf(io,"InvertRXD = 0x%02x \n",pd.InvertRXD);f()
    f()=@printf(io,"InvertRTS = 0x%02x \n",pd.InvertRTS);f()
    f()=@printf(io,"InvertCTS = 0x%02x \n",pd.InvertCTS);f()
    f()=@printf(io,"InvertDTR = 0x%02x \n",pd.InvertDTR);f()
    f()=@printf(io,"InvertDSR = 0x%02x \n",pd.InvertDSR);f()
    f()=@printf(io,"InvertDCD = 0x%02x \n",pd.InvertDCD);f()
    f()=@printf(io,"InvertRI = 0x%02x \n",pd.InvertRI);f()
    f()=@printf(io,"Cbus0 = 0x%02x \n",pd.Cbus0);f()
    f()=@printf(io,"Cbus1 = 0x%02x \n",pd.Cbus1);f()
    f()=@printf(io,"Cbus2 = 0x%02x \n",pd.Cbus2);f()
    f()=@printf(io,"Cbus3 = 0x%02x \n",pd.Cbus3);f()
    f()=@printf(io,"Cbus4 = 0x%02x \n",pd.Cbus4);f()
    f()=@printf(io,"RIsD2XX = 0x%02x \n",pd.RIsD2XX);f()
  end
  if pd.Version >=3
    println(io)
    println(io,"Rev 7 (FT2232H) Extensions")
    f()=@printf(io,"PullDownEnable7 = 0x%02x \n",pd.PullDownEnable7);f()
    f()=@printf(io,"SerNumEnable7 = 0x%02x \n",pd.SerNumEnable7);f()
    f()=@printf(io,"ALSlowSlew = 0x%02x \n",pd.ALSlowSlew);f()
    f()=@printf(io,"ALSchmittInput = 0x%02x \n",pd.ALSchmittInput);f()
    f()=@printf(io,"ALDriveCurrent = 0x%02x \n",pd.ALDriveCurrent);f()
    f()=@printf(io,"AHSlowSlew = 0x%02x \n",pd.AHSlowSlew);f()
    f()=@printf(io,"AHSchmittInput = 0x%02x \n",pd.AHSchmittInput);f()
    f()=@printf(io,"AHDriveCurrent = 0x%02x \n",pd.AHDriveCurrent);f()
    f()=@printf(io,"BLSlowSlew = 0x%02x \n",pd.BLSlowSlew);f()
    f()=@printf(io,"BLSchmittInput = 0x%02x \n",pd.BLSchmittInput);f()
    f()=@printf(io,"BLDriveCurrent = 0x%02x \n",pd.BLDriveCurrent);f()
    f()=@printf(io,"BHSlowSlew = 0x%02x \n",pd.BHSlowSlew);f()
    f()=@printf(io,"BHSchmittInput = 0x%02x \n",pd.BHSchmittInput);f()
    f()=@printf(io,"BHDriveCurrent = 0x%02x \n",pd.BHDriveCurrent);f()
    f()=@printf(io,"IFAIsFifo7 = 0x%02x \n",pd.IFAIsFifo7);f()
    f()=@printf(io,"IFAIsFifoTar7 = 0x%02x \n",pd.IFAIsFifoTar7);f()
    f()=@printf(io,"IFAIsFastSer7 = 0x%02x \n",pd.IFAIsFastSer7);f()
    f()=@printf(io,"AIsVCP7 = 0x%02x \n",pd.AIsVCP7);f()
    f()=@printf(io,"IFBIsFifo7 = 0x%02x \n",pd.IFBIsFifo7);f()
    f()=@printf(io,"IFBIsFifoTar7 = 0x%02x \n",pd.IFBIsFifoTar7);f()
    f()=@printf(io,"IFBIsFastSer7 = 0x%02x \n",pd.IFBIsFastSer7);f()
    f()=@printf(io,"BIsVCP7 = 0x%02x \n",pd.BIsVCP7);f()
    f()=@printf(io,"PowerSaveEnable = 0x%02x \n",pd.PowerSaveEnable);f()
  end
  if pd.Version >=4
    println(io)
    println(io,"Rev 8 (FT4232H) Extensions ")
    f()=@printf(io,"PullDownEnable8 = 0x%02x \n",pd.PullDownEnable8);f()
    f()=@printf(io,"SerNumEnable8 = 0x%02x \n",pd.SerNumEnable8);f()
    f()=@printf(io,"ASlowSlew = 0x%02x \n",pd.ASlowSlew);f()
    f()=@printf(io,"ASchmittInput = 0x%02x \n",pd.ASchmittInput);f()
    f()=@printf(io,"ADriveCurrent = 0x%02x \n",pd.ADriveCurrent);f()
    f()=@printf(io,"BSlowSlew = 0x%02x \n",pd.BSlowSlew);f()
    f()=@printf(io,"BSchmittInput = 0x%02x \n",pd.BSchmittInput);f()
    f()=@printf(io,"BDriveCurrent = 0x%02x \n",pd.BDriveCurrent);f()
    f()=@printf(io,"CSlowSlew = 0x%02x \n",pd.CSlowSlew);f()
    f()=@printf(io,"CSchmittInput = 0x%02x \n",pd.CSchmittInput);f()
    f()=@printf(io,"CDriveCurrent = 0x%02x \n",pd.CDriveCurrent);f()
    f()=@printf(io,"DSlowSlew = 0x%02x \n",pd.DSlowSlew);f()
    f()=@printf(io,"DSchmittInput = 0x%02x \n",pd.DSchmittInput);f()
    f()=@printf(io,"DDriveCurrent = 0x%02x \n",pd.DDriveCurrent);f()
    f()=@printf(io,"ARIIsTXDEN = 0x%02x \n",pd.ARIIsTXDEN);f()
    f()=@printf(io,"BRIIsTXDEN = 0x%02x \n",pd.BRIIsTXDEN);f()
    f()=@printf(io,"CRIIsTXDEN = 0x%02x \n",pd.CRIIsTXDEN);f()
    f()=@printf(io,"DRIIsTXDEN = 0x%02x \n",pd.DRIIsTXDEN);f()
    f()=@printf(io,"AIsVCP8 = 0x%02x \n",pd.AIsVCP8);f()
    f()=@printf(io,"BIsVCP8 = 0x%02x \n",pd.BIsVCP8);f()
    f()=@printf(io,"CIsVCP8 = 0x%02x \n",pd.CIsVCP8);f()
    f()=@printf(io,"DIsVCP8 = 0x%02x \n",pd.DIsVCP8);f()
  end
  if pd.Version >=5
    println(io)
    println(io,"Rev 9 (FT232H) Extensions")
    f()=@printf(io,"PullDownEnableH = 0x%02x \n",pd.PullDownEnableH);f()
    f()=@printf(io,"SerNumEnableH = 0x%02x \n",pd.SerNumEnableH);f()
    f()=@printf(io,"ACSlowSlewH = 0x%02x \n",pd.ACSlowSlewH);f()
    f()=@printf(io,"ACSchmittInputH = 0x%02x \n",pd.ACSchmittInputH);f()
    f()=@printf(io,"ACDriveCurrentH = 0x%02x \n",pd.ACDriveCurrentH);f()
    f()=@printf(io,"ADSlowSlewH = 0x%02x \n",pd.ADSlowSlewH);f()
    f()=@printf(io,"ADSchmittInputH = 0x%02x \n",pd.ADSchmittInputH);f()
    f()=@printf(io,"ADDriveCurrentH = 0x%02x \n",pd.ADDriveCurrentH);f()
    f()=@printf(io,"Cbus0H = 0x%02x \n",pd.Cbus0H);f()
    f()=@printf(io,"Cbus1H = 0x%02x \n",pd.Cbus1H);f()
    f()=@printf(io,"Cbus2H = 0x%02x \n",pd.Cbus2H);f()
    f()=@printf(io,"Cbus3H = 0x%02x \n",pd.Cbus3H);f()
    f()=@printf(io,"Cbus4H = 0x%02x \n",pd.Cbus4H);f()
    f()=@printf(io,"Cbus5H = 0x%02x \n",pd.Cbus5H);f()
    f()=@printf(io,"Cbus6H = 0x%02x \n",pd.Cbus6H);f()
    f()=@printf(io,"Cbus7H = 0x%02x \n",pd.Cbus7H);f()
    f()=@printf(io,"Cbus8H = 0x%02x \n",pd.Cbus8H);f()
    f()=@printf(io,"Cbus9H = 0x%02x \n",pd.Cbus9H);f()
    f()=@printf(io,"IsFifoH = 0x%02x \n",pd.IsFifoH);f()
    f()=@printf(io,"IsFifoTarH = 0x%02x \n",pd.IsFifoTarH);f()
    f()=@printf(io,"IsFastSerH = 0x%02x \n",pd.IsFastSerH);f()
    f()=@printf(io,"IsFT1248H = 0x%02x \n",pd.IsFT1248H);f()
    f()=@printf(io,"FT1248CpolH = 0x%02x \n",pd.FT1248CpolH);f()
    f()=@printf(io,"FT1248LsbH = 0x%02x \n",pd.FT1248LsbH);f()
    f()=@printf(io,"FT1248FlowControlH = 0x%02x \n",pd.FT1248FlowControlH);f()
    f()=@printf(io,"IsVCPH = 0x%02x \n",pd.IsVCPH);f()
    f()=@printf(io,"PowerSaveEnableH = 0x%02x \n",pd.PowerSaveEnableH);f()
  end
end

function ft_ee_read(ft_handle::Culong, version::Integer = 5)
  @assert version>-1
  ftpds = Ref{FtProgramData_C}(FtProgramData_C(version))
  ft_status = ccall((:FT_EE_Read, d2xx),
                     Cuint,
                     (Culong, Ref{FtProgramData_C}),
                     ft_handle, ftpds)
  checkstatus(ft_status)
  return FtProgramData(ftpds[])
end

function ft_ee_program(ft_handle::Culong, pd::FtProgramData)
  ftpds = Ref{FtProgramData_C}(FtProgramData_C(pd))
  ft_status = ccall((:FT_EE_Program, d2xx),
                     Cuint,
                     (Culong, Ref{FtProgramData_C}),
                     ft_handle, ftpds)
  checkstatus(ft_status)
  return nothing
end


text:
mutable struct MBESS2{TI<:Integer,TR<:Real} <: PointAlternative

  label::String
  samplespace::SampleSpace
  p0::TR
  pmcrv::TR
  prior
  mtoer::TR
  beta::TR
  minconditionalpower::TR
  MONOTONECONDITIONALPOWER::Bool
  npriorpivots::TI # number of pivots for prior evaluation

  function MBESS2{TI,TR}(
    label::String,
    samplespace::SampleSpace,
    p0::TR, pmcrv::TR, prior,
    alpha::TR, beta::TR,
    minconditionalpower::TR, MONOTONECONDITIONALPOWER::Bool,
    npriorpivots::TI
  ) where {TI<:Integer,TR<:Real}

    @checkprob p0 pmcrv alpha beta minconditionalpower
    z = quadgk(prior, 0, 1, abstol = .0001)[1]
    abs(z - 1) > .001 ?
      error(@sprintf("prior must integrate to one, is %.6f", z)) : nothing
    npriorpivots < 5 ?
      error(@sprintf("npriorpivots must be at least 5, is %i", npriorpivots)) : nothing
    new(
        label,
        samplespace,
        p0, pmcrv, prior,
        alpha, beta,
        minconditionalpower, MONOTONECONDITIONALPOWER, npriorpivots
    )

  end # inner constructor

end # MBESS2

function MBESS2(
  samplespace::SampleSpace,
  p0::Real, pmcrv::Real, prior;
  alpha::Real = 0.05, beta::Real = 0.2,
  minconditionalpower::Real = 0.0, MONOTONECONDITIONALPOWER::Bool = false,
  npriorpivots::Integer = 50,
  label::String = ""
)

  # unify types
  p0, pmcrv,alpha, beta, minconditionalpower =
    promote(p0, pmcrv, alpha, beta, minconditionalpower)

  MBESS2{typeof(npriorpivots),typeof(p0)}(
    label,
    samplespace,
    p0, pmcrv, prior,
    alpha, beta,
    minconditionalpower, MONOTONECONDITIONALPOWER,
    npriorpivots
  )

end # external constructor

Base.show(io::IO, params::MBESS2) = print("MBESS2")

maxsamplesize(params::MBESS2) = maxsamplesize(params.samplespace)

isgroupsequential(params::MBESS2) = isgroupsequential(params.ss)

hasmonotoneconditionalpower(params::MBESS2) = params.MONOTONECONDITIONALPOWER

minconditionalpower(params::MBESS2) = params.minconditionalpower

isunimodal(params::MBESS2) = true

prior(params::MBESS2, p) = params.prior(p)

function score(design::Design, params::MBESS2, p::T) where {T<:Real}

    @checkprob p
    ess = SampleSize(design, p) |> mean
    return ess

end # score

function score(design::Design, params::MBESS2)
    return quadgk(
        p -> prior(params, p) * score(design, params, p),
        0, 1, reltol = .001
    )[1]
end

function completemodel(ipm::IPModel, params::MBESS2, n1::Integer)

    ss = samplespace(params)
    !possible(n1, ss) ? error("n1 and sample space incompatible") : nothing
    # extract ip model
    m             = ipm.m
    y             = ipm.y
    nvals         = ipm.nvals
    cvals         = ipm.cvals
    cvalsfinite   = ipm.cvalsfinite
    cvalsinfinite = [-Inf; Inf]
    # extract other parameters
    nmax          = maxsamplesize(ss, n1)
    p0            = params.p0
    pmcrv         = params.pmcrv
    prior         = params.prior
    npriorpivots  = params.npriorpivots
    # add type one error rate constraint
    JuMP.@constraint(m,
        sum(dbinom(x1, n1, p0) * _cpr(x1, n1, n, c, p0) * y[x1, n, c] for
            x1 in 0:n1, n in nvals, c in cvals
        ) <= mtoer(params)
    )
    z = zeros(n1 + 1) # normalizing constants for prior conditional on p >= mcrv, X1=x1
    for x1 in 0:n1
        z[x1 + 1] = quadgk(p -> prior(p) * dbinom(x1, n1, p), pmcrv, 1, abstol = .001)[1]
    end
    JuMP.@expression(m, cep[x1 in 0:n1], # define expressions for conditional power given X1=x1
        sum(quadgk(p -> prior(p) * dbinom(x1, n1, p) * _cpr.(x1, n1, n, c, p), pmcrv, 1, abstol = 0.001)[1] / z[x1 + 1] * y[x1, n, c]
            for n in nvals, c in cvals
        )
    )
    for x1 in 0:n1
        JuMP.@constraint(m, # add conditional type two error rate constraint (power)
            cep[x1] >= minconditionalpower(params) * (1 - sum(y[x1, n1, c] for c in cvalsinfinite)) # must be conditional on continuation!
        )
        if (x1 >= 1) & hasmonotoneconditionalpower(params)
            JuMP.@constraint(m, # ensure monotonicity if required
                cep[x1] - cep[x1 - 1] >= 0
            )
        end
    end
    z = zeros(n1 + 1) # normalizing constant for prior conditional on X1=x1
    for x1 in 0:n1
        z[x1 + 1] = quadgk(p -> dbinom(x1, n1, p) * prior(p), 0, 1, abstol = .001)[1]
    end
    JuMP.@expression(m, ec[x1 in 0:n1], # expected sample size conditional on X1=x1
        sum(
            n * y[x1, n, c]
            for n in nvals, c in cvals
        )
    )

    JuMP.@constraint(m, # power on conditional prior quantile
        sum(
            dbinom(x1, n1, pmcrv) * _cpr(x1, n1, n, c, pmcrv) * y[x1, n, c]
            for x1 in 0:n1, n in nvals, c in cvals
        ) >= 1 - params.beta
    )
    prior_probs = zeros(n1 + 1)
    for x1 in 0:n1
        prior_probs[x1 + 1] = quadgk(p -> prior(p)*dbinom(x1, n1, p), 0, 1, abstol = .001)[1]
    end
    JuMP.@objective(m, Min,
        sum( ec[x1]*prior_probs[x1 + 1] for x1 in 0:n1 )
    )

    return true

end # completemodel

# ToDo: implement!
_isfeasible(design::Design, params::MBESS2) = true

max_stars_repo_name: kkmann/binaryTwoStageDesigns

max_issues_repo_name: kkmann/binaryTwoStageDesigns

max_forks_repo_name: kkmann/binaryTwoStageDesigns


text:
"""
A `SearchSpace` defines the valid candidate points that could be
considered in a search/optimization.
The base abstract class has very few restrictions
and can allow varying number of dimensions etc.
"""
abstract type SearchSpace end

"""
`SearchSpace` with a fixed finite number of dimensions.
Applicable to the vast majority of problems.
"""
abstract type FixedDimensionSearchSpace <: SearchSpace end

"""
Fixed-dimensional space, each dimension has a continuous range of valid values.
"""
abstract type ContinuousSearchSpace <: FixedDimensionSearchSpace end

"""
The point of the `SearchSpace`.

The abstract type. It allows different actual implementations to be used,
e.g `Vector` or `SubArray`.
"""
const AbstractIndividual = AbstractVector{Float64}

"""
The point of the `SearchSpace`.

The concrete type that could be used for storage.
"""
const Individual = Vector{Float64}

"""
The valid range of values for a specific dimension in a `SearchSpace`.
"""
const ParamBounds = Tuple{Float64,Float64}

"""
Get the range of valid values for a specific dimension.
"""
range_for_dim(css::ContinuousSearchSpace, i) = (mins(css)[i], maxs(css)[i])

ranges(css::ContinuousSearchSpace) = collect(zip(mins(css), maxs(css)))

"""
Generate `numIndividuals` individuals by random sampling in the search space.
"""
rand_individuals(css::ContinuousSearchSpace, numIndividuals) =
    mins(css) .+ deltas(css) .* rand(numdims(css), numIndividuals)

"""
Generate `numIndividuals` individuals by latin hypercube sampling (LHS).
This should be the default way to create the initial population.
"""
rand_individuals_lhs(css::ContinuousSearchSpace, numIndividuals) =
    Utils.latin_hypercube_sampling(mins(css), maxs(css), numIndividuals)

"""
Generate one random candidate.
"""
rand_individual(css::ContinuousSearchSpace) =
    mins(css) .+ deltas(css) .* rand(numdims(css))

"""
Check if given individual lies in the given search space.
"""
function Base.in(ind::AbstractIndividual, css::ContinuousSearchSpace)
    @assert length(ind) == numdims(css)
    @inbounds for i in eachindex(ind)
        (mins(css)[i] <= ind[i] <= maxs(css)[i]) || return false
    end
    return true
end

"""
`SearchSpace` defined by a range of valid values for each dimension.
"""
struct RangePerDimSearchSpace <: ContinuousSearchSpace
    # We save the ranges as individual mins, maxs and deltas for faster access later.
    mins::Vector{Float64}
    maxs::Vector{Float64}
    deltas::Vector{Float64}

    function RangePerDimSearchSpace(ranges)
        mins = getindex.(ranges, 1)
        maxs = getindex.(ranges, 2)
        new(mins, maxs, maxs .- mins)
    end

    RangePerDimSearchSpace(mins, maxs) = new(mins, maxs, maxs .- mins)
end

mins(rss::RangePerDimSearchSpace) = rss.mins
maxs(rss::RangePerDimSearchSpace) = rss.maxs
deltas(rss::RangePerDimSearchSpace) = rss.deltas
numdims(rss::RangePerDimSearchSpace) = length(mins(rss))

diameters(rss::RangePerDimSearchSpace) = deltas(rss)

Base.:(==)(a::RangePerDimSearchSpace, b::RangePerDimSearchSpace) =
    numdims(a) == numdims(b) && (a.mins == b.mins) && (a.maxs == b.maxs)

"""
Create `RangePerDimSearchSpace` with given number of dimensions
and given range of valid values for each dimension.
"""
symmetric_search_space(numdims, range=(0.0, 1.0)) = RangePerDimSearchSpace(fill(range, numdims))

"""
Projects a given point onto the search space coordinate-wise.
"""
feasible(v::AbstractIndividual, ss::RangePerDimSearchSpace) = clamp.(v, mins(ss), maxs(ss))

# concatenates two range-based search spaces
Base.vcat(ss1::RangePerDimSearchSpace, ss2::RangePerDimSearchSpace) =
    RangePerDimSearchSpace(vcat(mins(ss1), mins(ss2)),
                           vcat(maxs(ss1), maxs(ss2)))

"""
0-dimensional search space.
Could be used as a placeholder for optional `SearchSpace` parameters.
"""
const ZERO_SEARCH_SPACE = RangePerDimSearchSpace(Vector{Float64}(), Vector{Float64}())


text:
module ConstituencyTrees

using Reexport
@reexport using AbstractTrees

export ConstituencyTree
export pprint, read_tree, @tree_str

export POS, Words

export productions

export chomsky_normal_form, LeftFactored, RightFactored
export collapse_unary

export Treebank

include("trees.jl")
include("transformations.jl")

include("brackets.jl")
using .Brackets

include("treebanks.jl")

"""
    @tree_str(str)

String macro for reading a constituency parse tree from bracketed format.

    tree"(S (NP (DT the) (N cat)) (VP (V ate)))"
"""
macro tree_str(str)
    return read_tree(str)
end

end # module


text:
module Structs

import Random

struct UUID
    id::UInt64
end

new_uuid() = UUID(Random.rand(UInt64))

mutable struct Cell
    value
end
mutable struct ItemMut
    name::String
end

struct Item
    id::UUID
    cells::Array{Cell}
    other::ItemMut
end

new_item() = Item(new_uuid(), [], ItemMut(""))

mutable struct CategoryMut
    name::String
end
struct Category
    id::UUID
    items::Array{Item}
    other::CategoryMut
end

mutable struct WorksheetMut
    name::String
end
mutable struct Line
    value::Any
    items::Array{Item}
end

struct Worksheet
    id::UUID
    other::WorksheetMut
    categories::Array{Category}
end

struct Workbook
    sheets::Dict{UUID,Worksheet}
end

yak(x::Int64)::Int64 = x * 40

export Workbook, new_uuid

end # module

max_stars_repo_name: mesa-x/spreadsheet

max_issues_repo_name: mesa-x/spreadsheet

max_forks_repo_name: mesa-x/spreadsheet


text:
using Distributions
using LinearAlgebra
using StatsBase
using StaticArrays

import LinearAlgebra.isposdef

CovMat = (MMatrix{T, T, Float64} where T)
MeanVec = (MVector{T, Float64} where T)

struct MvNormalF{L}
    μ::MeanVec{L};
    Σ::CovMat{L};
    MvNormalF(μ::MeanVec{N}, Σ::CovMat{N}=CovMat{N}(diagm(0 => ones(N)))) where N = new{N}(μ, Σ)
    function MvNormalF(μ::T where T <: AbstractVector{Float64})
        if length(μ) == 2
            return MvNormalF(MeanVec{2}(μ))
        end

        return MvNormalF(MeanVec{3}(μ))
    end

    function MvNormalF(μ::T1 where T1 <: AbstractVector{Float64}, Σ::T2 where T2 <: AbstractMatrix{Float64})
        if length(μ) == 2
            return MvNormalF(MeanVec{2}(μ), CovMat{2}(Σ))
        end

        return MvNormalF(MeanVec{3}(μ), CovMat{3}(Σ))
    end
end

function wmean!(μ::MV where MV <: MeanVec, values::T where T <: AbstractMatrix{<:Real}, weights::T1 where T1 <: AbstractVector{<:Real})
    @assert length(μ) == size(values, 1)
    μ .= 0.0
    sum_w = 0.0
    for ci in 1:size(values, 2)
        w = fmax(weights[ci], 0.01)
        for ri in 1:length(μ)
            μ[ri] += values[ri, ci] * w
        end
        sum_w += w
    end

    μ ./= sum_w
    return μ
end

@inline @inbounds function log_pdf(d::MvNormalF{2}, x::SVector{2, Float64})::Float64
    std_x = sqrt(d.Σ[1])
    std_y = sqrt(d.Σ[4])
    ρ = fmax(fmin(1 - 1e-2, d.Σ[3] / (std_x * std_y)), -1 + 1e-2)

    ndx = (x[1] - d.μ[1]) / std_x
    ndy = (x[2] - d.μ[2]) / std_y

    div1 = 2 * (1 - ρ^2)
    log_div2 = log(2 * π * std_x * std_y * sqrt(1 - ρ^2))

    return -(ndx * ndx + ndy * ndy - 2 * ρ * ndx * ndy) / div1 - log_div2
end

@inline function log_pdf(d::MvNormalF{3}, x::SVector{3, Float64})::Float64 # TODO: pre-estimate divider and  inv(d.Σ)
    divider = (2π)^3 * det(d.Σ)
    dx = x .- d.μ
    return -0.5 * (dx') * inv(d.Σ) * dx - 0.5 * log(divider)
end

pdf(d::MvNormalF, x::SVector{N, Float64} where N) = exp(log_pdf(d, x))
shape(d::MvNormalF) = Matrix(d.Σ)

function estimate_sample_cov!(Σ::CovMat{N}, x::T where T <: AbstractMatrix{Float64}, weights::Nothing=nothing; μ::MeanVec{N}) where N
    # https://en.wikipedia.org/wiki/Estimation_of_covariance_matrices#Intrinsic_expectation
    Σ .= 0.0
    for i in 1:size(x, 2)
        for c in 1:size(Σ, 1)
            for r in 1:size(Σ, 1)
                Σ[r, c] += (x[c, i] - μ[c]) * (x[r, i] - μ[r])
            end
        end
    end

    Σ ./= size(x, 2)
    return Σ
end

function estimate_sample_cov!(Σ::CovMat{N}, x::T where T <: AbstractMatrix{Float64}, weights::T2 where T2 <: AbstractVector{<:Real}; μ::MeanVec{N}) where N
    # https://en.wikipedia.org/wiki/Estimation_of_covariance_matrices#Intrinsic_expectation
    Σ .= 0.0
    sum_w = 0.0
    for i in 1:size(x, 2)
        w = fmax(weights[i], 0.01)
        for c in 1:size(Σ, 1)
            for r in 1:size(Σ, 1)
                Σ[r, c] += w * (x[c, i] - μ[c]) * (x[r, i] - μ[r])
            end
        end
        sum_w += w
    end

    Σ ./= sum_w
    return Σ
end

function maximize!(dist::MvNormalF, x::T, confidences::T2 where T2 <: Union{AbstractVector{<:Real}, Nothing}=nothing)::MvNormalF where T <: AbstractMatrix{Float64}
    if size(x, 2) == 0
        return dist
    end

    if confidences === nothing
        mean!(dist.μ, x)
    else
        wmean!(dist.μ, x, confidences)
    end
    if size(x, 2) <= length(dist.μ)
        return dist
    end

    estimate_sample_cov!(dist.Σ, x, confidences; μ=dist.μ)
    return dist
end

isposdef(A::StaticMatrix) = LinearAlgebra.isposdef(cholesky(A))

function adjust_cov_matrix!(Σ::T; max_iter::Int=100, cov_modifier::Float64=1e-4, tol=1e-10)::T where T <: Union{CovMat{2}, CovMat{3}, Matrix{Float64}}
    if !issymmetric(Σ)
        error("Non-symmetric matrix: $Σ")
    end

    if isposdef(Σ) && det(Σ) > tol
        return Σ
    end

    for it in 1:max_iter
        if isposdef(Σ) && det(Σ) > tol
            break
        end

        @inbounds Σ[diagind(Σ)] .+= cov_modifier
        cov_modifier *= 1.5
    end

    return Σ
end


text:
using Convex
using Convex.ProblemDepot: run_tests
using Test
using SCS, ECOS, GLPK

using MathOptInterface
const MOI = MathOptInterface
const MOIU = MOI.Utilities

# Seed random number stream to improve test reliability
using Random
Random.seed!(2)

@testset "ProblemDepot" begin
    @testset "Problems can run without `solve!`ing if `test==false`; T=$T" for T in
                                                                               (
        Float64,
        BigFloat,
    )
        Convex.ProblemDepot.foreach_problem() do name, func
            @testset "$name" begin
                # We want to check to make sure this does not throw
                func(Val(false), 0.0, 0.0, T) do problem
                    @test problem isa Convex.Problem{T} # check numeric type
                    model = MOIU.MockOptimizer(MOIU.Model{T}())
                    return Convex.load_MOI_model!(model, problem) # make sure it loads without throwing
                end
            end
        end
    end
end

@testset "Definitions" begin
    include("definitions.jl")
end

@testset "Convex" begin
    include("test_utilities.jl")
    include("test_abstract_variable.jl")

    @testset "SCS with warmstarts" begin
        run_tests(
            exclude = [
                r"mip",
                # TODO(odow): investigate
                r"sdp_lieb_ando",
                # Tolerance issue with SCS 3.0
                r"sdp_Real_Variables_with_complex_equality_constraints",
            ],
        ) do p
            return solve!(
                p,
                MOI.OptimizerWithAttributes(
                    SCS.Optimizer,
                    "verbose" => 0,
                    "eps_rel" => 1e-6,
                    "eps_abs" => 1e-6,
                );
                warmstart = true,
            )
        end
    end

    @testset "SCS" begin
        # TODO(odow): investigate sdp_lieb_ando
        run_tests(; exclude = [r"mip", r"sdp_lieb_ando"]) do p
            return solve!(
                p,
                MOI.OptimizerWithAttributes(
                    SCS.Optimizer,
                    "verbose" => 0,
                    "eps_rel" => 1e-6,
                    "eps_abs" => 1e-6,
                ),
            )
        end
    end

    @testset "ECOS" begin
        run_tests(; exclude = [r"mip", r"sdp"]) do p
            return solve!(p, ECOS.Optimizer; silent_solver = true)
        end
    end

    @testset "GLPK" begin
        # Note this is an inclusion, not exclusion;
        # we only test GLPK with MIPs, since those we can't test elsewhere.
        run_tests([r"mip"]) do p
            return solve!(p, GLPK.Optimizer; silent_solver = true)
        end
    end
end


text:
using Base.Math: @horner, significand_bits, exponent_raw_max, exponent_bias

if VERSION < v"0.7.0-DEV.1430"
    using Base.Math: fpinttype
else
    using Base: uinttype
end

# log_fast from
# https://github.com/musm/SLEEF.jl/blob/c9dcd2eb090d69ec40790f19798c5fef2aba2616/src/log.jl

const MLN2  = 6.931471805599453094172321214581765680755001343602552541206800094933936219696955e-01 # log(2)

@inline float2integer(d::Float64) = (reinterpret(Int64, d) >> significand_bits(Float64)) % Int
@inline float2integer(d::Float32) = (reinterpret(Int32, d) >> significand_bits(Float32)) % Int

@inline function ilogb2k(d::T) where {T<:Union{Float32,Float64}}
    (float2integer(d) & exponent_raw_max(T)) - exponent_bias(T)
end

@inline function ldexp3k(x::T, e::Int) where {T<:Union{Float32,Float64}}
    @static if VERSION < v"0.7.0-DEV.1430"
        reinterpret(T, reinterpret(Unsigned, x) + (Int64(e) << significand_bits(T)) % fpinttype(T))
    else
        reinterpret(T, reinterpret(Unsigned, x) + (Int64(e) << significand_bits(T)) % uinttype(T))
    end
end

"""
    log_fast(x)
Compute the natural logarithm of `x`. The inverse of the natural logarithm is
the natural expoenential function `exp(x)`
"""
function log_fast end

let
global log_fast

c8d = 0.153487338491425068243146
c7d = 0.152519917006351951593857
c6d = 0.181863266251982985677316
c5d = 0.222221366518767365905163
c4d = 0.285714294746548025383248
c3d = 0.399999999950799600689777
c2d = 0.6666666666667778740063
c1d = 2.0

c5f = 0.2392828464508056640625f0
c4f = 0.28518211841583251953125f0
c3f = 0.400005877017974853515625f0
c2f = 0.666666686534881591796875f0
c1f = 2f0

global @inline log_fast_kernel(x::Float64) = @horner x c1d c2d c3d c4d c5d c6d c7d c8d
global @inline log_fast_kernel(x::Float32) = @horner x c1f c2f c3f c4f c5f

function log_fast(d::T) where {T<:Union{Float32,Float64}}
    o = d < realmin(T)
    o && (d *= T(Int64(1) << 32) * T(Int64(1) << 32))

    e = ilogb2k(d * T(1.0/0.75))
    m = ldexp3k(d, -e)
    o && (e -= 64)

    x  = (m - 1) / (m + 1)
    x2 = x * x

    t = log_fast_kernel(x2)

    x = x * t + T(MLN2) * e

    isinf(d) && (x = T(Inf))
    (d < 0 || isnan(d)) && (x = T(NaN))
    d == 0 && (x = -T(Inf))

    return x
end
end

log_fast(x::Union{Int32,Int64}) = log_fast(float(x))

# Derivatives

@init @require ForwardDiff="f6369f11-7733-5829-9624-2563aa707210" begin
  function log_fast(d::ForwardDiff.Dual{T,<:Union{Float32,Float64}}) where T
    x = ForwardDiff.value(d)
    Dual{T}(log_fast(x), inv(x) * ForwardDiff.partials(d))
  end
end


text:
using PyPlot, Colors, PerceptualColourMaps
using QuadDIRECT
using QuadDIRECT: Box

get_finite(x, default) = isfinite(x) ? x : default
outerbounds(b1, b2) = (min(b1[1], b2[1]), max(b1[2], b2[2]))
outerbounds(b1, b2::Real) = (min(b1[1], b2), max(b1[2], b2))
outerbounds_finite(b1, b2) = (min(b1[1], get_finite(b2[1], b1[1])), max(b1[2], get_finite(b2[2], b1[2])))
widenbounds(b) = (Δx = 0.1*(b[2]-b[1]); return (b[1]-Δx, b[2]+Δx))

function plotbounds(root::Box{T,2}, x0, lower, upper) where T
    xbounds, ybounds = (Inf, -Inf), (Inf, -Inf)
    bb = Vector{Tuple{T,T}}(undef, 2)
    x = [NaN, NaN]
    flag = [false, false]
    for box in leaves(root)
        for i = 1:2
            bb[i] = (lower[i], upper[i])
        end
        QuadDIRECT.boxbounds!(bb, box)
        xbounds = outerbounds_finite(xbounds, bb[1])
        ybounds = outerbounds_finite(ybounds, bb[2])
        x = QuadDIRECT.position!(x, flag, box)
        QuadDIRECT.default_position!(x, flag, x0)
        xbounds = outerbounds(xbounds, x[1])
        ybounds = outerbounds(ybounds, x[2])
    end
    widenbounds(xbounds), widenbounds(ybounds)
end

function plotboxes(root::Box{T,2}, x0, lower, upper, xbounds::Tuple{Any,Any}, ybounds::Tuple{Any,Any}; clim=extrema(root), cs::AbstractVector{<:Colorant}=cmap("RAINBOW3")) where T
    clf()
    for bx in leaves(root)
        plotrect(bx, x0, clim, cs, lower, upper, xbounds, ybounds)
    end
    xlim(xbounds)
    ylim(ybounds)
    ax = gca()
    # norm = PyPlot.matplotlib[:colors][:Normalize](vmin=clim[1], vmax=clim[2])
    # cb = PyPlot.matplotlib[:colorbar][:ColorbarBase](ax, cmap=ColorMap(cs), norm=norm)
    ax
end
plotboxes(root::Box{T,2}, x0, lower, upper; clim=extrema(root), cs::AbstractVector{<:Colorant}=cmap("RAINBOW3")) where T =
    plotboxes(root, x0, lower, upper, plotbounds(root, x0, lower, upper)...; clim=clim, cs=cs)

function plotrect(box::Box{T,2}, x0, clim, cs, lower, upper, xbounds, ybounds) where T
    @assert(QuadDIRECT.isleaf(box))
    x = QuadDIRECT.position(box, x0)
    bb = QuadDIRECT.boxbounds(box, lower, upper)
    bbx, bby = bb
    rectx = [bbx[1], bbx[2], bbx[2], bbx[1], bbx[1]]
    recty = [bby[1], bby[1], bby[2], bby[2], bby[1]]
    fval = box.parent.fvalues[box.parent_cindex]
    cnorm = (clamp(fval, clim...) - clim[1])/(clim[2] - clim[1])
    col = cs[round(Int, (length(cs)-1)*cnorm) + 1]
    hold(true)
    fill(clamp.(rectx, xbounds...), clamp.(recty, ybounds...), color=[red(col), green(col), blue(col)])
    plot(rectx, recty, "k")
    plot([x[1]], [x[2]], "k.")
    hold(false)
    nothing
end


text:
struct FlattenIterator{T}
    name::Symbol
    value::T
end

FlattenIterator(name, value) = FlattenIterator(Symbol(name), value)

Base.length(iter::FlattenIterator) = _length(iter.value)
_length(a) = length(a)
_length(a::AbstractArray) = sum(_length, a)

Base.eltype(::Type{FlattenIterator{T}}) where T = Tuple{Symbol,_eltype(T)}
_eltype(::Type{T}) where T = eltype(T)
_eltype(::Type{TA}) where {TA<:AbstractArray} = _eltype(eltype(TA))

@inline function Base.iterate(iter::FlattenIterator{<:Number}, i = 1)
    i === 1 && return (iter.name, iter.value), 2
    return nothing
end
@inline function Base.iterate(
    iter::FlattenIterator{<:AbstractArray{<:Number}},
    ind = (1,),
)
    i = ind[1]
    i > length(iter.value) && return nothing
    name = getname(iter, i)
    return (name, iter.value[i]), (i+1,)
end
@inline function Base.iterate(
    iter::FlattenIterator{T},
    ind = startind(T),
) where {T <: AbstractArray}
    i = ind[1]
    i > length(iter.value) && return nothing
    name = getname(iter, i)
    local out
    while i <= length(iter.value)
        v = iter.value[i]
        out = iterate(FlattenIterator(name, v), Base.tail(ind))
        out !== nothing && break
        i += 1
    end
    if out === nothing
        return nothing
    else
        return out[1], (i, out[2]...)
    end
end

@inline startind(::Type{<:AbstractArray{T}}) where {T} = (1, startind(T)...)
@inline startind(::Type{<:Number}) = ()
@inline startind(::Type{<:Any}) = throw("Type not supported.")
@inline function getname(iter::FlattenIterator, i::Int)
    return Symbol(iter.name, "[", join(ind2sub(size(iter.value), i), ","), "]")
end
@inline ind2sub(v, i) = Tuple(CartesianIndices(v)[i])


text:
function run(s)
    # Your code here
    joltages = readlines(IOBuffer(s))
    joltages = [parse(Int, j) for j in joltages]
    sort!(joltages)
    pushfirst!(joltages, 0)
    cache = zeros(Int, size(joltages))
    cache[1] = 1
    for i in 1:length(joltages)
        if (i - 1 > 0) && (joltages[i] - joltages[i - 1] <= 3)
            cache[i] += cache[i - 1]
        end
        if (i - 2 > 0) && (joltages[i] - joltages[i - 2] <= 3)
            cache[i] += cache[i - 2]
        end
        if (i - 3 > 0) && (joltages[i] - joltages[i - 3] <= 3)
            cache[i] += cache[i - 3]
        end
    end
    return cache[end]
end

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

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

main()


text:
include("common.jl")
using RecursiveArrayTools

@testset "Reinitialization" begin
    alg = MethodOfSteps(BS3(); constrained=false)

    @testset for inplace in (true, false)
        prob = inplace ? prob_dde_1delay : prob_dde_1delay_scalar_notinplace

        @testset "integrator" begin
            integrator = init(prob, alg, dt= 0.01)
            solve!(integrator)

            u = recursivecopy(integrator.sol.u)
            t = copy(integrator.sol.t)

            reinit!(integrator)
            integrator.dt = 0.01
            solve!(integrator)

            @test u == integrator.sol.u
            @test t == integrator.sol.t
        end

        @testset "solution" begin
            integrator = init(prob, alg, dt= 0.01, tstops = [0.5], saveat = [0.33])
            sol = solve!(integrator)

            u = recursivecopy(sol.u)
            t = copy(sol.t)

            reinit!(integrator)
            integrator.dt = 0.01
            sol = solve!(integrator)

            @test u == sol.u
            @test t == sol.t
        end
    end
end


text:
"""
"""
function fit!(
        transformer::ImmutablePackageSingleLabelPredictProbaTransformer,
        varargs...;
        kwargs...
        )
    if length(varargs) == 1
        return varargs[1]
    else
        return varargs
    end
end

"""
"""
function predict(
        transformer::ImmutablePackageSingleLabelPredictProbaTransformer,
        varargs...;
        kwargs...
        )
    if length(varargs) == 1
        return varargs[1]
    else
        return varargs
    end
end

"""
"""
function predict_proba(
        transformer::ImmutablePackageSingleLabelPredictProbaTransformer,
        single_labelprobabilities::AbstractDict;
        kwargs...
        )
    result = Dict()
    result[transformer.single_label_name] = single_labelprobabilities
    result = fix_type(result)
    return result
end


text:
@with_kw mutable struct Legend
    handles::Vector{DrawingHandle} = DrawingHandle[]
    labels::Vector{Union{String,Vector{String}}} = String[]
    # ---
    position::Option{String}   = ∅
    textstyle::TextStyle       = TextStyle()
    offset  ::T2F              = (0.0, 0.0)
    bgcolor ::Option{Colorant} = ∅
    margins ::Option{T2F}      = ∅
    nobox   ::Bool             = false
    off     ::Bool             = false
    # TODO: can this take a textstyle?
    # entries *not* contained in the struct, they're generated elsewhere
    # nobox      ::Option{Bool}                = ∅
end


text:
# Creating a test problem
include("spline_kernel.jl")

# Creating generators U,V that result in a positive-definite matrix K
t = Vector(0.1:0.1:1)
n = length(t); p = 2;
U, V = spline_kernel(t, p);
K = SymSemiseparable(U,V);
x = randn(K.n);
Kfull = tril(U*V') + triu(V*U',1);

# Testing multiplication
@test isapprox(K*x, Kfull*x, atol = 1e-6)

# Testing multiplication with the adjoint operator
@test isapprox(K'*x, Kfull'*x, atol = 1e-6)

# Testing linear solves
@test isapprox(K*(K\x),x, atol=1e-6)
@test isapprox(K'*(K'\x),x, atol=1e-6)


text:
module WaveSimulator

using Base.Cartesian, ComputationalResources, TiledIteration, ProgressMeter, ValueHistories

export

    CPU1,
    CPUThreads,
    CUDALibs,

    UniformWave,
    BoxDomain,
    Simulator,
    simulate,
    simulate_gauss,
    simulate!,
    update!,
    toimage

abstract type Domain{N} end
abstract type State{N,T,D<:Domain} end
abstract type Wave{N,T<:AbstractFloat} end
abstract type Backend{R<:AbstractResource} end
abstract type CPUBackend{R<:AbstractResource} <: Backend{R} end

include("wave.jl")
include("simulator.jl")
include("boxdomain.jl")
include("utils.jl")
include("hooks.jl")
include("backends/cpu.jl")
using CUDAapi
if has_cuda()
    include("backends/cuda.jl")
end

end


text:
using GLMakie, LinearAlgebra, GeometryBasics

begin
    scene = Scene(backgroundcolor=:gray, resolution=(500, 500))
    sub1 = Scene(scene, px_area = Rect2f(0, 0, 250, 500), backgroundcolor=:white, clear=true)
    scene
end

begin
    sub2 = Scene(scene, px_area = Rect2f(250, 0, 250, 500), backgroundcolor=(:gray, 0.5), clear=true, camera=nothing)
    scene
end

# By default, the scenes goes from -1 to 1.
# So to draw a rectangle outlining the screen, the following rectangle does the job:
lines!(sub1, Rect2f(-1, -1, 2, 2), linewidth=5)
# this is, because the projection matrix and view matrix is the identity matrix:
sub1.camera

# One can change the mapping, to e.g. draw from -3 to 5:
sub1.camera.projection[] = Makie.orthographicprojection(-3f0, 5f0, -3f0, 5f0, -100f0, 100f0)
# which changes the position of our rectangle:
scene

# one can also change it to a perspective, 3d projection
w, h = size(sub1)
sub1.camera.projection[] = Makie.perspectiveprojection(45f0, Float32(w / h), 0.1f0, 100f0)
# Now, we also need to change the view matrix, to "put" the camera into some place.
sub1.camera.view[] = Makie.lookat(Vec3f(10), Vec3f(0), Vec3f(0, 0, 1))

# One can also resize scenes dynamically:

sub2.px_area[] = Rect2i(125, 125, 250, 250)
lines!(sub2, Rect2f(-1, -1, 2, 2), linewidth=5)
sub2.clear = false
scene

# Without clear, this will create a see through scene...
# We give that new sub scene a 3d camera,
sub3 = Scene(sub2, camera=cam3d!, clear=false)
meshscatter!(sub3, rand(Point3f, 10))
center!(sub3)
scene

# this way we get an outline, that always strokes the parent scene, and then
# we can put a 3d scene inside of that.


text:
include("../src/heapqueue.jl")
using .HeapQueueModule

testdata = [30, 10, 35, 15, 12, 40, 23, 20]

@testset "min heap queue works" begin
    minhq = heapify(testdata, Min)

    @test popfirst!(minhq) == 10
    @test popfirst!(minhq) == 12
    @test popfirst!(minhq) == 15

    minhq = heapify(testdata, Min)
    for _ = 1:(length(minhq)-1)
        popfirst!(minhq)
    end
    @test popfirst!(minhq) == 40
end

@testset "max heap queue works" begin
    maxhq = heapify(testdata, Max)
    @test popfirst!(maxhq) == 40
    @test popfirst!(maxhq) == 35
    @test popfirst!(maxhq) == 30

    maxhq = heapify(testdata, Max)
    for _ = 1:(length(maxhq)-1)
        popfirst!(maxhq)
    end
    @test popfirst!(maxhq) == 10
end

@testset "test heapify!" begin
    data = deepcopy(testdata)
    hq = heapify!(data, Min)
    result = Int[]
    while !isempty(data)
        push!(result, popfirst!(hq))
    end
    @test result == [10, 12, 15, 20, 23, 30, 35, 40]
end

function testsort(sortfunc, testpairs)
    for (arr, ans) in testpairs
        temparr = deepcopy(arr)
        sortfunc(temparr)
        @test temparr == ans
    end
end

@testset "heapsort" begin
    testpairs = [
            ([], []),
            ([1], [1]),
            ([3, 1, 2], [1, 2, 3]),
            ([1, 3, 2], [1, 2, 3]),
            ([1, 2, 3], [1, 2, 3]),
            ([4, 2, 3, 1], [1, 2, 3, 4]),
            ([4, 3, 3, 1, -1], [-1, 1, 3, 3, 4]),
            (['b', 'c', 'a'], ['a', 'b', 'c']),
            (['E', 'A', 'S', 'Y', 'Q', 'U',
              'E', 'S', 'T', 'I', 'O', 'N'],
             ['A', 'E', 'E', 'I', 'N', 'O',
              'Q', 'S', 'S', 'T', 'U', 'Y'])
        ]

    testsort(heapsort!, testpairs)
end

@testset "Indexed heap sort" begin
    m1 = Base.split("A B C F G I I Z")
    m2 = Base.split("B D H P Q Q")
    m3 = Base.split("A B E F J N")
    orig_streams = [m1, m2, m3]

    @testset "Indexed Min HQ" begin
        # the multiway merge example on:
        # https://algs4.cs.princeton.edu/24pq/Multiway.java.html
        output = []
        streams = deepcopy(orig_streams)
        hq = HeapQueueModule.IndexedMinHQ{String}(3)
        HeapQueueModule.insert!(hq, 1, popfirst!(streams[1]))
        while !isempty(hq)
            for i in 1:3
                if !HeapQueueModule.contains(hq, i) && !isempty(streams[i])
                    new_elem = popfirst!(streams[i])
                    HeapQueueModule.insert!(hq, i, new_elem)
                end
            end
            _, firstkey = HeapQueueModule.popfirst!(hq)
            push!(output, firstkey)
        end

        @test join(output, " ") == "A A B B B C D E F F G H I I J N P Q Q Z"
    end

    @testset "Test change key" begin
        hq = HeapQueueModule.IndexedMinHQ{Float64}(5)
        HeapQueueModule.insert!(hq, 1, 3)
        HeapQueueModule.insert!(hq, 2, 1)
        HeapQueueModule.insert!(hq, 3, 2)
        @test_throws HeapQueueModule.InvalidKeyChangeError decreasekey!(hq, 3, 3)

        decreasekey!(hq, 3, 0.5)
        @test HeapQueueModule.popfirst!(hq) == (3, 0.5)
    end

end

max_stars_repo_name: Jetafull/AlgorithmsInJulia

max_issues_repo_name: Jetafull/algorithms-in-julia

max_forks_repo_name: Jetafull/algorithms-in-julia


text:
using Test
import SPH
import WAV

function make_sph_header(;coding="pcm")
    header = Dict{String, Any}(
        "channel_count"      => 1,
        "sample_rate"        => 8000,
        "sample_count"       => 8000
    )
    if coding != nothing
        header["sample_coding"] = coding
    end
    if coding in ["pcm", nothing]
        header["sample_byte_format"] = "0123"
        header["sample_n_bytes"] = 4
    else
        @assert coding in ["ulaw", "alaw"]
        header["sample_n_bytes"] = 1
    end
    return header
end

function test_sph2wav()
    samples = sin.(2 * pi * [0:7999;] * 440.0 / 8000) * 0.01
    sph_filename = tempname()
    wav_filename = tempname()
    header = make_sph_header()
    SPH.sphwrite(header, samples, sph_filename)
    SPH.sph2wav(sph_filename, wav_filename)
    wav_samples, fs = WAV.wavread(wav_filename)
    rm(sph_filename)
    rm(wav_filename)
    @test all(isapprox.(wav_samples, samples; atol=1e-9))
end

function test_sph_roundtrip(;coding="pcm")
    header = make_sph_header(coding=coding)
    samples = sin.(2 * pi * [0:7999;] * 440.0 / 8000) * 0.01
    sph_filename = tempname()
    SPH.sphwrite(header, samples, sph_filename)
    sph_header, sph_samples = SPH.sphread(sph_filename)
    rm(sph_filename)
    @test Set(keys(header)) == Set(keys(sph_header))
    @test all([header[k] == sph_header[k] for k in keys(header)])
    tolerance = coding in ["pcm", nothing] ? 1e-9 : 1e-3
    @test all(isapprox.(sph_samples, samples; atol=tolerance))
end

test_sph2wav()
# nothing == sample_coding not specified in header, should assume pcm in this case
for coding in ["pcm", "ulaw", "alaw", nothing]
    test_sph_roundtrip(coding=coding)
end


text:
module TopOptProblems

using Ferrite, StaticArrays, LinearAlgebra
using SparseArrays, Setfield, Requires
using ..TopOpt.Utilities
using ..TopOpt: PENALTY_BEFORE_INTERPOLATION
using ..Utilities: @forward_property
using Distributions: Distributions

using VTKDataTypes

import Ferrite: assemble!
const QuadraticHexahedron = Ferrite.Cell{3,20,6}

abstract type AbstractTopOptProblem end

include("grids.jl")
include("metadata.jl")
include("problem_types.jl")
include("multiload.jl")
include("elementmatrix.jl")
include("matrices_and_vectors.jl")
include("elementinfo.jl")
include("assemble.jl")
include("buckling.jl")

include(joinpath("IO", "IO.jl"))
using .InputOutput

include("Visualization/Visualization.jl")
using .Visualization

export RayProblem,
    PointLoadCantilever,
    HalfMBB,
    LBeam,
    TieBeam,
    InpStiffness,
    StiffnessTopOptProblem,
    AbstractTopOptProblem,
    GlobalFEAInfo,
    ElementFEAInfo,
    YoungsModulus,
    assemble,
    assemble_f!,
    RaggedArray,
    ElementMatrix,
    rawmatrix,
    bcmatrix,
    save_mesh,
    RandomMagnitude,
    MultiLoad

end # module


text:
if CUDA.functional()
    @testset "CUDA methods" begin
        w = ConvFFT((100,), nConvDims=1)
        @test cu(w.fftPlan) isa CUFFT.rCuFFTPlan # does cu work on the fft plans when applied directly?
        cw = cu(w)
        @test cw.weight isa CuArray # does cu work on the weights?
        @test cw.fftPlan isa CUFFT.rCuFFTPlan # does cu work on the fftPlan?
        cw1 = gpu(w)
        @test cw1.weight isa CuArray # does gpu work on the weights?
        @test cw1.fftPlan isa CUFFT.rCuFFTPlan # does gpu work on the fftPlan?
        w1 = cpu(cw)
        @test w1.weight isa Array # does cpu work on the weights?
        @test w1.fftPlan isa FFTW.rFFTWPlan # does cpu work on the fftPlan?
        x = randn(100)
        cx = cu(x)
        @test cw(cx) isa CuArray
        @test cw(cx) ≈ cu(w(x)) # CUDA and cpu version get the same result approximately
        ∇cu = gradient(t -> cw(t)[1], cx)[1]
        ∇ = gradient(t -> w(t)[1], x)[1]
        @test ∇ ≈ cpu(∇cu)
        w1 = waveletLayer((100, 1, 1))
        w1(x)
        cw1 = cu(w1)
        @test cw1(cx) ≈ cu(w1(x))

        ∇cu = gradient(t -> abs(cw1(t)[1]), cx)[1]
        ∇ = gradient(t -> abs(w1(t)[1]), x)[1]
        @test ∇ ≈ cpu(∇cu)
    end
end


text:
import Base: LineEdit, REPL

mutable struct SQLCompletionProvider <: LineEdit.CompletionProvider
    l::REPL.LineEditREPL
end

function return_callback(p::LineEdit.PromptState)
    # TODO ... something less dumb
    buf = take!(copy(LineEdit.buffer(p)))
    # local sp = 0
    # for c in buf
    #   c == '(' && (sp += 1; continue)
    #   c == ')' && (sp -= 1; continue)
    # end
    # sp <= 0
    return true
end

function evaluate_sql(s::String)
    global odbcdf
    global dsn
    try
        odbcdf = ODBC.query(dsn, s)
    catch e
        println(STDOUT, "error during sql evaluation: ", e)
        return nothing
    end
    println(STDOUT, odbcdf)
end

function setup_repl(enabled::Bool)
    # bail out if we don't have a repl
    !isdefined(Base, :active_repl) && return

    repl = Base.active_repl
    main_mode = Base.active_repl.interface.modes[1]

    # disable repl if requested
    if (!enabled)
        delete!(main_mode.keymap_dict, ']')
        return
    end

    panel = LineEdit.Prompt("sql> ";
                            prompt_prefix = Base.text_colors[:white],
                            prompt_suffix = main_mode.prompt_suffix,
                            on_enter = return_callback)

    hp = main_mode.hist
    hp.mode_mapping[:sql] = panel
    panel.hist = hp
    panel.on_done = REPL.respond(evaluate_sql, repl, panel;
                                 pass_empty = false)
    panel.complete = nothing

    sql_keymap = Dict{Any,Any}(
        ']' =>
            function (s,args...)
                if isempty(s) || position(LineEdit.buffer(s)) == 0
                    buf = copy(LineEdit.buffer(s))
                    LineEdit.transition(s, panel) do
                        LineEdit.state(s, panel).input_buffer = buf
                    end
                else
                    LineEdit.edit_insert(s, ']')
                end
            end)

    search_prompt, skeymap = LineEdit.setup_search_keymap(hp)
    mk = REPL.mode_keymap(main_mode)
    b = Dict{Any,Any}[skeymap, mk, LineEdit.history_keymap, LineEdit.default_keymap, LineEdit.escape_defaults]
    panel.keymap_dict = LineEdit.keymap(b)

    main_mode.keymap_dict = LineEdit.keymap_merge(main_mode.keymap_dict, sql_keymap)
    nothing
end

toggle_sql_repl(; enabled::Bool = true) = setup_repl(enabled)


text:
# --------------------------------------------------------------------------
# Quick version of functions (for testing)
q_gradloglik(mu,cov,x) = cov\(mu-x)
# --------------------------------------------------------------------------

Random.seed!(123)

# Parameters for the gaussians
p   = 50         # dimensions
P1  = randn(p,p) # precision
P1 *= P1'        # make the precision positive def
mu  = randn(p)   # mean
C1  = inv(P1)    # covariance
C1 += C1'
C1 /= 2          # stabilise the covariance

# Define gaussians using the different notations
mvg       = MvGaussianCanon(mu, P1)
mvg2      = MvGaussianNatural(P1*mu,-P1)
mvg_distr = Distributions.MvNormal(mu, C1)
mvg_da    = MvGaussianCanon(mu, 0.25 * diagm(0=>ones(length(mu))))
mvg_db    = MvDiagonalGaussian(mu, 2.0*ones(p))

# we don't care about constants, but in Distributions
# they do so we need to compensate for that
check_loglik(x) = Distributions.logpdf(mvg_distr, x) +
                    0.5 * (p * log(2pi) + log(det(C1)))

xvals = [randn(p) for i in 1:25]

# difference is in logspace, and we're using slightly different matrices and
# the computation of the constant is crude to say the least -> higher tol
@test maximum(abs.(collect(loglik(mvg, x) - check_loglik(x) for x ∈ xvals))) <= 1e-6

# canon to natural
@test maximum(abs.(collect(loglik(mvg, x) - loglik(mvg2, x) for x ∈ xvals))) <= 1e-10

# standard to diagonal
@test maximum(abs.(collect(loglik(mvg_da, x) - loglik(mvg_db, x) for x ∈ xvals))) <= 1e-10

# gradloglik, expect a difference since C1 was stabilised
@test maximum(norm(gradloglik(mvg, x) - q_gradloglik(mu, C1, x))
                    for x in xvals ) <= 1e-6

# gradloglik standard to diagonal
@test maximum(norm(gradloglik(mvg_da, x) - gradloglik(mvg_db, x))
                    for x in xvals ) <= 1e-10


text:
"""
Для установки LibPQ необходимо выполнить команды

import Pkg

Pkg.add("LibPQ")
Pkg.add("BinaryProvider")

include("/Users/kuznetsovin/.julia/packages/LibPQ/PeS3p/deps/build.jl")
"""

using DataFrames, LibPQ, Statistics

conn = LibPQ.Connection("dbname=track")

function getPgData()::DataFrame
    @info "Get data"
    df = @time DataFrame(execute(conn, "SELECT client,packet_id,navigate_date,received_date,nsat FROM vts.track"))

    @info "Aggregate data"
    result = @time by(df, :client, :packet_id => length, :navigate_date => minimum, :navigate_date => maximum, :nsat => mean)

    return result
    end;

max_stars_repo_name: kuznetsovin/julia-first-app

max_issues_repo_name: kuznetsovin/julia-first-app

max_forks_repo_name: kuznetsovin/julia-first-app


text:
using SparseGrids
using Base.Test

# Moments of exp(-x^2)
function gaussmoment(m::Int)
	@assert m >= 0

	if isodd(m)
		return 0.0
	elseif iseven(m)
		m2 = div(m,2)
		return prod( 1:2:m-1 ) * sqrt(pi) / 2^m2
	end
end

# Moments of exp(-|x|^2)
function gaussmoment( P::Vector{Int} )
	I = 1.0
	for d = 1:length(P)
		I *= gaussmoment(P[d])
	end

	return I
end

# Like gaussmoment, but with quadrature rule
function gaussquad( P::Vector, nodes::Matrix, weights::Vector )
	# Evaluate integrand
	F = broadcast( ^, nodes, P )
	I = vec(prod(F,1))

	# Evaluate quadrature sum
	Q = dot( I, weights )

	return Q
end

# ------------------------------------------------------------
# Test quadrature for various dimensions and orders
# Note: It is not interesting to test uneven moments for Gauss-Hermite

# Dimension and order
D = 3
order = 4

# Moments to test
vecs = Vector{Vector{Int}}(D)
for d in 1:D
	vecs[d] = [0:order;]
end
P = combvec( vecs )

M = size(P, 2)

for generator = [FastGaussQuadrature.gausshermite, kpn]
	# Quadrature points and weights
	N, W = sparsegrid( D, order, generator )

	# Maximum degree for which the generator gives correct results
	generator == FastGaussQuadrature.gausshermite ?  max_degree = 2*order-1 : max_degree = D*order

	for m = 1:M
		# Test if all moments are even
		curP = P[:,m]

		if all(map(iseven, curP))
			I = gaussmoment(curP)
			Q = gaussquad(curP, N, W)

			# Expected test result depends on the total degree
			if sum(curP) <= max_degree
				@test_approx_eq I Q
			else
				@test abs(I - Q) > 1e-3
			end
		end
	end
end


text:
using RekFiles
using Test

@testset "RekFiles.jl" begin
    # Write your tests here.
end

max_stars_repo_name: pjsjipt/RekFiles

max_issues_repo_name: pjsjipt/RekFiles

max_forks_repo_name: pjsjipt/RekFiles


text:
"""
    visualize(curr::Field, filename=:none)

Create a heatmap of a temperature field. Optionally write png file.
"""
function visualize(curr::Field, filename=:none)
    background_color = :white

    plot = heatmap(
        curr.data,
        colorbar_title = "Temperature (C)",
        background_color = background_color
    )

    if filename != :none
        savefig(filename)
    else
        display(plot)
    end
end


text:
using MatrixOptInterface

const MatOI = MatrixOptInterface
const MOI = MatOI.MOI
const MOIU = MatOI.MOIU
const MOIB = MOI.Bridges

raw_lp = MatOI.LPSolverForm{Float64}(
    MOI.MIN_SENSE,
    [4,3],
    [1 2;2 1],
    [3, 3],
    [MatOI.LESS_THAN, MatOI.LESS_THAN],
    [-Inf, -Inf],
    [Inf, Inf]
)

model = MatOI.MatrixOptimizer(raw_lp)

@show model

MOIU.@model(ModelData, (), (),
            (MOI.Zeros, MOI.Nonnegatives),
            (), (), (), (), (MOI.VectorAffineFunction,))

const cache = MOIU.UniversalFallback(ModelData{Float64}())
opt = MatOI.Optimizer()
MOI.empty!(cache)
cached = MOIU.CachingOptimizer(cache, opt)
bridged = MOIB.full_bridge_optimizer(cached, Float64)

MOI.copy_to(bridged, model, copy_names = false)

MOI.optimize!(bridged)

@show opt.data

@show MatOI.LPSolverForm(opt)


text:
using SymPy

mu, eta, dt, lambda = @vars mu eta dt lambda
S = [
    1+2/3*mu*dt/eta -1/3*mu*dt/eta 0.0
    -1/3*mu*dt/eta 1+2/3*mu*dt/eta 0.0
    0.0 0.0 1+mu*dt/eta
]
invS = inv(S)
H = invS * [
    2*mu+lambda lambda 0.0
    lambda 2mu+lambda 0.0
    0.0 0.0 mu
]
S = simplify(invS)
H = simplify(H)

k = -1
s = ""
for i = 1:3
    for j = 1:3
        global k += 1
        c = sympy.ccode(S[i,j])
        global s *= "s[9*i+$k] = $c;\n"
    end
end
s = s*"\n\n"

k = -1
for i = 1:3
    for j = 1:3
        global k += 1
        c = sympy.ccode(H[i,j])
        global s *= "h[9*i+$k] = $c;\n"
    end
end

println(s)

gs11, gs12, gs13, gs21, gs22, gs23, gs31, gs32, gs33 = @vars gs11 gs12 gs13 gs21 gs22 gs23 gs31 gs32 gs33
gs = [
    gs11 gs12 gs13
    gs21 gs22 gs23
    gs31 gs32 gs33
]

hs11, hs12, hs13, hs21, hs22, hs23, hs31, hs32, hs33 = @vars hs11 hs12 hs13 hs21 hs22 hs23 hs31 hs32 hs33
hs = [
    hs11 hs12 hs13
    hs21 hs22 hs23
    hs31 hs32 hs33
]

a = sum(S .* gs)
gmu = diff(a, mu)|>simplify
geta = diff(a, eta)|>simplify
glambda = diff(a, lambda)|>simplify

s = ""
k = -1
for i = 1:3
    for j = 1:3
        global k += 1
        global s *= "double gs$i$j = grad_s[9*i+$k];\n"
    end
end

s *= "grad_mu_all[i] += "*sympy.ccode(gmu)*";\n"
s *= "grad_eta_all[i] += "*sympy.ccode(geta)*";\n"
s *= "grad_lambda_all[i] += "*sympy.ccode(glambda)*";\n\n"

a = sum(H .* hs)
gmu = diff(a, mu)|>simplify
geta = diff(a, eta)|>simplify
glambda = diff(a, lambda)|>simplify

k = -1
for i = 1:3
    for j = 1:3
        global k += 1
        global s *= "double hs$i$j = grad_h[9*i+$k];\n"
    end
end

s *= "grad_mu_all[i] += "*sympy.ccode(gmu)*";\n"
s *= "grad_eta_all[i] += "*sympy.ccode(geta)*";\n"
s *= "grad_lambda_all[i] += "*sympy.ccode(glambda)*";\n"

println(s)