text:
const cudaHostAllocDefault = 0x00
const cudaHostAllocPortable = 0x01
const cudaHostAllocMapped = 0x02
const cudaHostAllocWriteCombined = 0x04
const cudaHostRegisterDefault = 0x00
const cudaHostRegisterPortable = 0x01
const cudaHostRegisterMapped = 0x02
const cudaPeerAccessDefault = 0x00
const cudaStreamDefault = 0x00
const cudaStreamNonBlocking = 0x01
const cudaEventDefault = 0x00
const cudaEventBlockingSync = 0x01
const cudaEventDisableTiming = 0x02
const cudaEventInterprocess = 0x04
const cudaDeviceScheduleAuto = 0x00
const cudaDeviceScheduleSpin = 0x01
const cudaDeviceScheduleYield = 0x02
const cudaDeviceScheduleBlockingSync = 0x04
const cudaDeviceBlockingSync = 0x04
const cudaDeviceScheduleMask = 0x07
const cudaDeviceMapHost = 0x08
const cudaDeviceLmemResizeToMax = 0x10
const cudaDeviceMask = 0x01
const cudaArrayDefault = 0x00
const cudaArrayLayered = 0x01
const cudaArraySurfaceLoadStore = 0x02
const cudaArrayCubemap = 0x04
const cudaArrayTextureGather = 0x08
const cudaIpcMemLazyEnablePeerAccess = 0x01
const cudaMemAttachGlobal = 0x01
const cudaMemAttachHost = 0x02
const cudaMemAttachSingle = 0x04

# Skipping MacroDefinition: cudaDevicePropDontCare { { '\0' } , /* char   name[256];               */ 0 , /* size_t totalGlobalMem;          */ 0 , /* size_t sharedMemPerBlock;       */ 0 , /* int    regsPerBlock;            */ 0 , /* int    warpSize;                */ 0 , /* size_t memPitch;                */ 0 , /* int    maxThreadsPerBlock;      */ { 0 , 0 , 0 } , /* int    maxThreadsDim[3];        */ { 0 , 0 , 0 } , /* int    maxGridSize[3];          */ 0 , /* int    clockRate;               */ 0 , /* size_t totalConstMem;           */ - 1 , /* int    major;                   */ - 1 , /* int    minor;                   */ 0 , /* size_t textureAlignment;        */ 0 , /* size_t texturePitchAlignment    */ - 1 , /* int    deviceOverlap;           */ 0 , /* int    multiProcessorCount;     */ 0 , /* int    kernelExecTimeoutEnabled */ 0 , /* int    integrated               */ 0 , /* int    canMapHostMemory         */ 0 , /* int    computeMode              */ 0 , /* int    maxTexture1D             */ 0 , /* int    maxTexture1DMipmap       */ 0 , /* int    maxTexture1DLinear       */ { 0 , 0 } , /* int    maxTexture2D[2]          */ { 0 , 0 } , /* int    maxTexture2DMipmap[2]    */ { 0 , 0 , 0 } , /* int    maxTexture2DLinear[3]    */ { 0 , 0 } , /* int    maxTexture2DGather[2]    */ { 0 , 0 , 0 } , /* int    maxTexture3D[3]          */ { 0 , 0 , 0 } , /* int    maxTexture3DAlt[3]       */ 0 , /* int    maxTextureCubemap        */ { 0 , 0 } , /* int    maxTexture1DLayered[2]   */ { 0 , 0 , 0 } , /* int    maxTexture2DLayered[3]   */ { 0 , 0 } , /* int    maxTextureCubemapLayered[2] */ 0 , /* int    maxSurface1D             */ { 0 , 0 } , /* int    maxSurface2D[2]          */ { 0 , 0 , 0 } , /* int    maxSurface3D[3]          */ { 0 , 0 } , /* int    maxSurface1DLayered[2]   */ { 0 , 0 , 0 } , /* int    maxSurface2DLayered[3]   */ 0 , /* int    maxSurfaceCubemap        */ { 0 , 0 } , /* int    maxSurfaceCubemapLayered[2] */ 0 , /* size_t surfaceAlignment         */ 0 , /* int    concurrentKernels        */ 0 , /* int    ECCEnabled               */ 0 , /* int    pciBusID                 */ 0 , /* int    pciDeviceID              */ 0 , /* int    pciDomainID              */ 0 , /* int    tccDriver                */ 0 , /* int    asyncEngineCount         */ 0 , /* int    unifiedAddressing        */ 0 , /* int    memoryClockRate          */ 0 , /* int    memoryBusWidth           */ 0 , /* int    l2CacheSize              */ 0 , /* int    maxThreadsPerMultiProcessor */ 0 , /* int    streamPrioritiesSupported */ 0 , /* int    globalL1CacheSupported   */ 0 , /* int    localL1CacheSupported    */ 0 , /* size_t sharedMemPerMultiprocessor; */ 0 , /* int    regsPerMultiprocessor;   */ 0 , /* int    managedMemory            */ 0 , /* int    isMultiGpuBoard          */ 0 , /* int    multiGpuBoardGroupID     */ }

const CUDA_IPC_HANDLE_SIZE = 64

# begin enum cudaError
typealias cudaError Uint32
const cudaSuccess = (uint32)(0)
const cudaErrorMissingConfiguration = (uint32)(1)
const cudaErrorMemoryAllocation = (uint32)(2)
const cudaErrorInitializationError = (uint32)(3)
const cudaErrorLaunchFailure = (uint32)(4)
const cudaErrorPriorLaunchFailure = (uint32)(5)
const cudaErrorLaunchTimeout = (uint32)(6)
const cudaErrorLaunchOutOfResources = (uint32)(7)
const cudaErrorInvalidDeviceFunction = (uint32)(8)
const cudaErrorInvalidConfiguration = (uint32)(9)
const cudaErrorInvalidDevice = (uint32)(10)
const cudaErrorInvalidValue = (uint32)(11)
const cudaErrorInvalidPitchValue = (uint32)(12)
const cudaErrorInvalidSymbol = (uint32)(13)
const cudaErrorMapBufferObjectFailed = (uint32)(14)
const cudaErrorUnmapBufferObjectFailed = (uint32)(15)
const cudaErrorInvalidHostPointer = (uint32)(16)
const cudaErrorInvalidDevicePointer = (uint32)(17)
const cudaErrorInvalidTexture = (uint32)(18)
const cudaErrorInvalidTextureBinding = (uint32)(19)
const cudaErrorInvalidChannelDescriptor = (uint32)(20)
const cudaErrorInvalidMemcpyDirection = (uint32)(21)
const cudaErrorAddressOfConstant = (uint32)(22)
const cudaErrorTextureFetchFailed = (uint32)(23)
const cudaErrorTextureNotBound = (uint32)(24)
const cudaErrorSynchronizationError = (uint32)(25)
const cudaErrorInvalidFilterSetting = (uint32)(26)
const cudaErrorInvalidNormSetting = (uint32)(27)
const cudaErrorMixedDeviceExecution = (uint32)(28)
const cudaErrorCudartUnloading = (uint32)(29)
const cudaErrorUnknown = (uint32)(30)
const cudaErrorNotYetImplemented = (uint32)(31)
const cudaErrorMemoryValueTooLarge = (uint32)(32)
const cudaErrorInvalidResourceHandle = (uint32)(33)
const cudaErrorNotReady = (uint32)(34)
const cudaErrorInsufficientDriver = (uint32)(35)
const cudaErrorSetOnActiveProcess = (uint32)(36)
const cudaErrorInvalidSurface = (uint32)(37)
const cudaErrorNoDevice = (uint32)(38)
const cudaErrorECCUncorrectable = (uint32)(39)
const cudaErrorSharedObjectSymbolNotFound = (uint32)(40)
const cudaErrorSharedObjectInitFailed = (uint32)(41)
const cudaErrorUnsupportedLimit = (uint32)(42)
const cudaErrorDuplicateVariableName = (uint32)(43)
const cudaErrorDuplicateTextureName = (uint32)(44)
const cudaErrorDuplicateSurfaceName = (uint32)(45)
const cudaErrorDevicesUnavailable = (uint32)(46)
const cudaErrorInvalidKernelImage = (uint32)(47)
const cudaErrorNoKernelImageForDevice = (uint32)(48)
const cudaErrorIncompatibleDriverContext = (uint32)(49)
const cudaErrorPeerAccessAlreadyEnabled = (uint32)(50)
const cudaErrorPeerAccessNotEnabled = (uint32)(51)
const cudaErrorDeviceAlreadyInUse = (uint32)(54)
const cudaErrorProfilerDisabled = (uint32)(55)
const cudaErrorProfilerNotInitialized = (uint32)(56)
const cudaErrorProfilerAlreadyStarted = (uint32)(57)
const cudaErrorProfilerAlreadyStopped = (uint32)(58)
const cudaErrorAssert = (uint32)(59)
const cudaErrorTooManyPeers = (uint32)(60)
const cudaErrorHostMemoryAlreadyRegistered = (uint32)(61)
const cudaErrorHostMemoryNotRegistered = (uint32)(62)
const cudaErrorOperatingSystem = (uint32)(63)
const cudaErrorPeerAccessUnsupported = (uint32)(64)
const cudaErrorLaunchMaxDepthExceeded = (uint32)(65)
const cudaErrorLaunchFileScopedTex = (uint32)(66)
const cudaErrorLaunchFileScopedSurf = (uint32)(67)
const cudaErrorSyncDepthExceeded = (uint32)(68)
const cudaErrorLaunchPendingCountExceeded = (uint32)(69)
const cudaErrorNotPermitted = (uint32)(70)
const cudaErrorNotSupported = (uint32)(71)
const cudaErrorHardwareStackError = (uint32)(72)
const cudaErrorIllegalInstruction = (uint32)(73)
const cudaErrorMisalignedAddress = (uint32)(74)
const cudaErrorInvalidAddressSpace = (uint32)(75)
const cudaErrorInvalidPc = (uint32)(76)
const cudaErrorIllegalAddress = (uint32)(77)
const cudaErrorInvalidPtx = (uint32)(78)
const cudaErrorInvalidGraphicsContext = (uint32)(79)
const cudaErrorStartupFailure = (uint32)(127)
const cudaErrorApiFailureBase = (uint32)(10000)
# end enum cudaError

# begin enum cudaChannelFormatKind
typealias cudaChannelFormatKind Uint32
const cudaChannelFormatKindSigned = (uint32)(0)
const cudaChannelFormatKindUnsigned = (uint32)(1)
const cudaChannelFormatKindFloat = (uint32)(2)
const cudaChannelFormatKindNone = (uint32)(3)
# end enum cudaChannelFormatKind

immutable cudaChannelFormatDesc
    x::Cint
    y::Cint
    z::Cint
    w::Cint
    f::cudaChannelFormatKind
end

typealias cudaArray Void
typealias cudaArray_t Ptr{cudaArray}
typealias cudaArray_const_t Ptr{cudaArray}
typealias cudaMipmappedArray Void
typealias cudaMipmappedArray_t Ptr{cudaMipmappedArray}
typealias cudaMipmappedArray_const_t Ptr{cudaMipmappedArray}

# begin enum cudaMemoryType
typealias cudaMemoryType Uint32
const cudaMemoryTypeHost = (uint32)(1)
const cudaMemoryTypeDevice = (uint32)(2)
# end enum cudaMemoryType

# begin enum cudaMemcpyKind
typealias cudaMemcpyKind Uint32
const cudaMemcpyHostToHost = (uint32)(0)
const cudaMemcpyHostToDevice = (uint32)(1)
const cudaMemcpyDeviceToHost = (uint32)(2)
const cudaMemcpyDeviceToDevice = (uint32)(3)
const cudaMemcpyDefault = (uint32)(4)
# end enum cudaMemcpyKind

immutable cudaPitchedPtr
    ptr::Ptr{Void}
    pitch::Csize_t
    xsize::Csize_t
    ysize::Csize_t
end

immutable cudaExtent
    width::Csize_t
    height::Csize_t
    depth::Csize_t
end

immutable cudaPos
    x::Csize_t
    y::Csize_t
    z::Csize_t
end

immutable cudaMemcpy3DParms
    srcArray::cudaArray_t
    srcPos::cudaPos
    srcPtr::cudaPitchedPtr
    dstArray::cudaArray_t
    dstPos::cudaPos
    dstPtr::cudaPitchedPtr
    extent::cudaExtent
    kind::cudaMemcpyKind
end

immutable cudaMemcpy3DPeerParms
    srcArray::cudaArray_t
    srcPos::cudaPos
    srcPtr::cudaPitchedPtr
    srcDevice::Cint
    dstArray::cudaArray_t
    dstPos::cudaPos
    dstPtr::cudaPitchedPtr
    dstDevice::Cint
    extent::cudaExtent
end

typealias cudaGraphicsResource Void

# begin enum cudaGraphicsRegisterFlags
typealias cudaGraphicsRegisterFlags Uint32
const cudaGraphicsRegisterFlagsNone = (uint32)(0)
const cudaGraphicsRegisterFlagsReadOnly = (uint32)(1)
const cudaGraphicsRegisterFlagsWriteDiscard = (uint32)(2)
const cudaGraphicsRegisterFlagsSurfaceLoadStore = (uint32)(4)
const cudaGraphicsRegisterFlagsTextureGather = (uint32)(8)
# end enum cudaGraphicsRegisterFlags

# begin enum cudaGraphicsMapFlags
typealias cudaGraphicsMapFlags Uint32
const cudaGraphicsMapFlagsNone = (uint32)(0)
const cudaGraphicsMapFlagsReadOnly = (uint32)(1)
const cudaGraphicsMapFlagsWriteDiscard = (uint32)(2)
# end enum cudaGraphicsMapFlags

# begin enum cudaGraphicsCubeFace
typealias cudaGraphicsCubeFace Uint32
const cudaGraphicsCubeFacePositiveX = (uint32)(0)
const cudaGraphicsCubeFaceNegativeX = (uint32)(1)
const cudaGraphicsCubeFacePositiveY = (uint32)(2)
const cudaGraphicsCubeFaceNegativeY = (uint32)(3)
const cudaGraphicsCubeFacePositiveZ = (uint32)(4)
const cudaGraphicsCubeFaceNegativeZ = (uint32)(5)
# end enum cudaGraphicsCubeFace

# begin enum cudaResourceType
typealias cudaResourceType Uint32
const cudaResourceTypeArray = (uint32)(0)
const cudaResourceTypeMipmappedArray = (uint32)(1)
const cudaResourceTypeLinear = (uint32)(2)
const cudaResourceTypePitch2D = (uint32)(3)
# end enum cudaResourceType

# begin enum cudaResourceViewFormat
typealias cudaResourceViewFormat Uint32
const cudaResViewFormatNone = (uint32)(0)
const cudaResViewFormatUnsignedChar1 = (uint32)(1)
const cudaResViewFormatUnsignedChar2 = (uint32)(2)
const cudaResViewFormatUnsignedChar4 = (uint32)(3)
const cudaResViewFormatSignedChar1 = (uint32)(4)
const cudaResViewFormatSignedChar2 = (uint32)(5)
const cudaResViewFormatSignedChar4 = (uint32)(6)
const cudaResViewFormatUnsignedShort1 = (uint32)(7)
const cudaResViewFormatUnsignedShort2 = (uint32)(8)
const cudaResViewFormatUnsignedShort4 = (uint32)(9)
const cudaResViewFormatSignedShort1 = (uint32)(10)
const cudaResViewFormatSignedShort2 = (uint32)(11)
const cudaResViewFormatSignedShort4 = (uint32)(12)
const cudaResViewFormatUnsignedInt1 = (uint32)(13)
const cudaResViewFormatUnsignedInt2 = (uint32)(14)
const cudaResViewFormatUnsignedInt4 = (uint32)(15)
const cudaResViewFormatSignedInt1 = (uint32)(16)
const cudaResViewFormatSignedInt2 = (uint32)(17)
const cudaResViewFormatSignedInt4 = (uint32)(18)
const cudaResViewFormatHalf1 = (uint32)(19)
const cudaResViewFormatHalf2 = (uint32)(20)
const cudaResViewFormatHalf4 = (uint32)(21)
const cudaResViewFormatFloat1 = (uint32)(22)
const cudaResViewFormatFloat2 = (uint32)(23)
const cudaResViewFormatFloat4 = (uint32)(24)
const cudaResViewFormatUnsignedBlockCompressed1 = (uint32)(25)
const cudaResViewFormatUnsignedBlockCompressed2 = (uint32)(26)
const cudaResViewFormatUnsignedBlockCompressed3 = (uint32)(27)
const cudaResViewFormatUnsignedBlockCompressed4 = (uint32)(28)
const cudaResViewFormatSignedBlockCompressed4 = (uint32)(29)
const cudaResViewFormatUnsignedBlockCompressed5 = (uint32)(30)
const cudaResViewFormatSignedBlockCompressed5 = (uint32)(31)
const cudaResViewFormatUnsignedBlockCompressed6H = (uint32)(32)
const cudaResViewFormatSignedBlockCompressed6H = (uint32)(33)
const cudaResViewFormatUnsignedBlockCompressed7 = (uint32)(34)
# end enum cudaResourceViewFormat

immutable cudaResourceDesc
    resType::cudaResourceType
    res::Void
end

immutable cudaResourceViewDesc
    format::cudaResourceViewFormat
    width::Csize_t
    height::Csize_t
    depth::Csize_t
    firstMipmapLevel::Uint32
    lastMipmapLevel::Uint32
    firstLayer::Uint32
    lastLayer::Uint32
end

immutable cudaPointerAttributes
    memoryType::cudaMemoryType
    device::Cint
    devicePointer::Ptr{Void}
    hostPointer::Ptr{Void}
    isManaged::Cint
end

immutable cudaFuncAttributes
    sharedSizeBytes::Csize_t
    constSizeBytes::Csize_t
    localSizeBytes::Csize_t
    maxThreadsPerBlock::Cint
    numRegs::Cint
    ptxVersion::Cint
    binaryVersion::Cint
    cacheModeCA::Cint
end

# begin enum cudaFuncCache
typealias cudaFuncCache Uint32
const cudaFuncCachePreferNone = (uint32)(0)
const cudaFuncCachePreferShared = (uint32)(1)
const cudaFuncCachePreferL1 = (uint32)(2)
const cudaFuncCachePreferEqual = (uint32)(3)
# end enum cudaFuncCache

# begin enum cudaSharedMemConfig
typealias cudaSharedMemConfig Uint32
const cudaSharedMemBankSizeDefault = (uint32)(0)
const cudaSharedMemBankSizeFourByte = (uint32)(1)
const cudaSharedMemBankSizeEightByte = (uint32)(2)
# end enum cudaSharedMemConfig

# begin enum cudaComputeMode
typealias cudaComputeMode Uint32
const cudaComputeModeDefault = (uint32)(0)
const cudaComputeModeExclusive = (uint32)(1)
const cudaComputeModeProhibited = (uint32)(2)
const cudaComputeModeExclusiveProcess = (uint32)(3)
# end enum cudaComputeMode

# begin enum cudaLimit
typealias cudaLimit Uint32
const cudaLimitStackSize = (uint32)(0)
const cudaLimitPrintfFifoSize = (uint32)(1)
const cudaLimitMallocHeapSize = (uint32)(2)
const cudaLimitDevRuntimeSyncDepth = (uint32)(3)
const cudaLimitDevRuntimePendingLaunchCount = (uint32)(4)
# end enum cudaLimit

# begin enum cudaOutputMode
typealias cudaOutputMode Uint32
const cudaKeyValuePair = (uint32)(0)
const cudaCSV = (uint32)(1)
# end enum cudaOutputMode

# begin enum cudaDeviceAttr
typealias cudaDeviceAttr Uint32
const cudaDevAttrMaxThreadsPerBlock = (uint32)(1)
const cudaDevAttrMaxBlockDimX = (uint32)(2)
const cudaDevAttrMaxBlockDimY = (uint32)(3)
const cudaDevAttrMaxBlockDimZ = (uint32)(4)
const cudaDevAttrMaxGridDimX = (uint32)(5)
const cudaDevAttrMaxGridDimY = (uint32)(6)
const cudaDevAttrMaxGridDimZ = (uint32)(7)
const cudaDevAttrMaxSharedMemoryPerBlock = (uint32)(8)
const cudaDevAttrTotalConstantMemory = (uint32)(9)
const cudaDevAttrWarpSize = (uint32)(10)
const cudaDevAttrMaxPitch = (uint32)(11)
const cudaDevAttrMaxRegistersPerBlock = (uint32)(12)
const cudaDevAttrClockRate = (uint32)(13)
const cudaDevAttrTextureAlignment = (uint32)(14)
const cudaDevAttrGpuOverlap = (uint32)(15)
const cudaDevAttrMultiProcessorCount = (uint32)(16)
const cudaDevAttrKernelExecTimeout = (uint32)(17)
const cudaDevAttrIntegrated = (uint32)(18)
const cudaDevAttrCanMapHostMemory = (uint32)(19)
const cudaDevAttrComputeMode = (uint32)(20)
const cudaDevAttrMaxTexture1DWidth = (uint32)(21)
const cudaDevAttrMaxTexture2DWidth = (uint32)(22)
const cudaDevAttrMaxTexture2DHeight = (uint32)(23)
const cudaDevAttrMaxTexture3DWidth = (uint32)(24)
const cudaDevAttrMaxTexture3DHeight = (uint32)(25)
const cudaDevAttrMaxTexture3DDepth = (uint32)(26)
const cudaDevAttrMaxTexture2DLayeredWidth = (uint32)(27)
const cudaDevAttrMaxTexture2DLayeredHeight = (uint32)(28)
const cudaDevAttrMaxTexture2DLayeredLayers = (uint32)(29)
const cudaDevAttrSurfaceAlignment = (uint32)(30)
const cudaDevAttrConcurrentKernels = (uint32)(31)
const cudaDevAttrEccEnabled = (uint32)(32)
const cudaDevAttrPciBusId = (uint32)(33)
const cudaDevAttrPciDeviceId = (uint32)(34)
const cudaDevAttrTccDriver = (uint32)(35)
const cudaDevAttrMemoryClockRate = (uint32)(36)
const cudaDevAttrGlobalMemoryBusWidth = (uint32)(37)
const cudaDevAttrL2CacheSize = (uint32)(38)
const cudaDevAttrMaxThreadsPerMultiProcessor = (uint32)(39)
const cudaDevAttrAsyncEngineCount = (uint32)(40)
const cudaDevAttrUnifiedAddressing = (uint32)(41)
const cudaDevAttrMaxTexture1DLayeredWidth = (uint32)(42)
const cudaDevAttrMaxTexture1DLayeredLayers = (uint32)(43)
const cudaDevAttrMaxTexture2DGatherWidth = (uint32)(45)
const cudaDevAttrMaxTexture2DGatherHeight = (uint32)(46)
const cudaDevAttrMaxTexture3DWidthAlt = (uint32)(47)
const cudaDevAttrMaxTexture3DHeightAlt = (uint32)(48)
const cudaDevAttrMaxTexture3DDepthAlt = (uint32)(49)
const cudaDevAttrPciDomainId = (uint32)(50)
const cudaDevAttrTexturePitchAlignment = (uint32)(51)
const cudaDevAttrMaxTextureCubemapWidth = (uint32)(52)
const cudaDevAttrMaxTextureCubemapLayeredWidth = (uint32)(53)
const cudaDevAttrMaxTextureCubemapLayeredLayers = (uint32)(54)
const cudaDevAttrMaxSurface1DWidth = (uint32)(55)
const cudaDevAttrMaxSurface2DWidth = (uint32)(56)
const cudaDevAttrMaxSurface2DHeight = (uint32)(57)
const cudaDevAttrMaxSurface3DWidth = (uint32)(58)
const cudaDevAttrMaxSurface3DHeight = (uint32)(59)
const cudaDevAttrMaxSurface3DDepth = (uint32)(60)
const cudaDevAttrMaxSurface1DLayeredWidth = (uint32)(61)
const cudaDevAttrMaxSurface1DLayeredLayers = (uint32)(62)
const cudaDevAttrMaxSurface2DLayeredWidth = (uint32)(63)
const cudaDevAttrMaxSurface2DLayeredHeight = (uint32)(64)
const cudaDevAttrMaxSurface2DLayeredLayers = (uint32)(65)
const cudaDevAttrMaxSurfaceCubemapWidth = (uint32)(66)
const cudaDevAttrMaxSurfaceCubemapLayeredWidth = (uint32)(67)
const cudaDevAttrMaxSurfaceCubemapLayeredLayers = (uint32)(68)
const cudaDevAttrMaxTexture1DLinearWidth = (uint32)(69)
const cudaDevAttrMaxTexture2DLinearWidth = (uint32)(70)
const cudaDevAttrMaxTexture2DLinearHeight = (uint32)(71)
const cudaDevAttrMaxTexture2DLinearPitch = (uint32)(72)
const cudaDevAttrMaxTexture2DMipmappedWidth = (uint32)(73)
const cudaDevAttrMaxTexture2DMipmappedHeight = (uint32)(74)
const cudaDevAttrComputeCapabilityMajor = (uint32)(75)
const cudaDevAttrComputeCapabilityMinor = (uint32)(76)
const cudaDevAttrMaxTexture1DMipmappedWidth = (uint32)(77)
const cudaDevAttrStreamPrioritiesSupported = (uint32)(78)
const cudaDevAttrGlobalL1CacheSupported = (uint32)(79)
const cudaDevAttrLocalL1CacheSupported = (uint32)(80)
const cudaDevAttrMaxSharedMemoryPerMultiprocessor = (uint32)(81)
const cudaDevAttrMaxRegistersPerMultiprocessor = (uint32)(82)
const cudaDevAttrManagedMemory = (uint32)(83)
const cudaDevAttrIsMultiGpuBoard = (uint32)(84)
const cudaDevAttrMultiGpuBoardGroupID = (uint32)(85)
# end enum cudaDeviceAttr

immutable Array_256_Uint8
    d1::Uint8
    d2::Uint8
    d3::Uint8
    d4::Uint8
    d5::Uint8
    d6::Uint8
    d7::Uint8
    d8::Uint8
    d9::Uint8
    d10::Uint8
    d11::Uint8
    d12::Uint8
    d13::Uint8
    d14::Uint8
    d15::Uint8
    d16::Uint8
    d17::Uint8
    d18::Uint8
    d19::Uint8
    d20::Uint8
    d21::Uint8
    d22::Uint8
    d23::Uint8
    d24::Uint8
    d25::Uint8
    d26::Uint8
    d27::Uint8
    d28::Uint8
    d29::Uint8
    d30::Uint8
    d31::Uint8
    d32::Uint8
    d33::Uint8
    d34::Uint8
    d35::Uint8
    d36::Uint8
    d37::Uint8
    d38::Uint8
    d39::Uint8
    d40::Uint8
    d41::Uint8
    d42::Uint8
    d43::Uint8
    d44::Uint8
    d45::Uint8
    d46::Uint8
    d47::Uint8
    d48::Uint8
    d49::Uint8
    d50::Uint8
    d51::Uint8
    d52::Uint8
    d53::Uint8
    d54::Uint8
    d55::Uint8
    d56::Uint8
    d57::Uint8
    d58::Uint8
    d59::Uint8
    d60::Uint8
    d61::Uint8
    d62::Uint8
    d63::Uint8
    d64::Uint8
    d65::Uint8
    d66::Uint8
    d67::Uint8
    d68::Uint8
    d69::Uint8
    d70::Uint8
    d71::Uint8
    d72::Uint8
    d73::Uint8
    d74::Uint8
    d75::Uint8
    d76::Uint8
    d77::Uint8
    d78::Uint8
    d79::Uint8
    d80::Uint8
    d81::Uint8
    d82::Uint8
    d83::Uint8
    d84::Uint8
    d85::Uint8
    d86::Uint8
    d87::Uint8
    d88::Uint8
    d89::Uint8
    d90::Uint8
    d91::Uint8
    d92::Uint8
    d93::Uint8
    d94::Uint8
    d95::Uint8
    d96::Uint8
    d97::Uint8
    d98::Uint8
    d99::Uint8
    d100::Uint8
    d101::Uint8
    d102::Uint8
    d103::Uint8
    d104::Uint8
    d105::Uint8
    d106::Uint8
    d107::Uint8
    d108::Uint8
    d109::Uint8
    d110::Uint8
    d111::Uint8
    d112::Uint8
    d113::Uint8
    d114::Uint8
    d115::Uint8
    d116::Uint8
    d117::Uint8
    d118::Uint8
    d119::Uint8
    d120::Uint8
    d121::Uint8
    d122::Uint8
    d123::Uint8
    d124::Uint8
    d125::Uint8
    d126::Uint8
    d127::Uint8
    d128::Uint8
    d129::Uint8
    d130::Uint8
    d131::Uint8
    d132::Uint8
    d133::Uint8
    d134::Uint8
    d135::Uint8
    d136::Uint8
    d137::Uint8
    d138::Uint8
    d139::Uint8
    d140::Uint8
    d141::Uint8
    d142::Uint8
    d143::Uint8
    d144::Uint8
    d145::Uint8
    d146::Uint8
    d147::Uint8
    d148::Uint8
    d149::Uint8
    d150::Uint8
    d151::Uint8
    d152::Uint8
    d153::Uint8
    d154::Uint8
    d155::Uint8
    d156::Uint8
    d157::Uint8
    d158::Uint8
    d159::Uint8
    d160::Uint8
    d161::Uint8
    d162::Uint8
    d163::Uint8
    d164::Uint8
    d165::Uint8
    d166::Uint8
    d167::Uint8
    d168::Uint8
    d169::Uint8
    d170::Uint8
    d171::Uint8
    d172::Uint8
    d173::Uint8
    d174::Uint8
    d175::Uint8
    d176::Uint8
    d177::Uint8
    d178::Uint8
    d179::Uint8
    d180::Uint8
    d181::Uint8
    d182::Uint8
    d183::Uint8
    d184::Uint8
    d185::Uint8
    d186::Uint8
    d187::Uint8
    d188::Uint8
    d189::Uint8
    d190::Uint8
    d191::Uint8
    d192::Uint8
    d193::Uint8
    d194::Uint8
    d195::Uint8
    d196::Uint8
    d197::Uint8
    d198::Uint8
    d199::Uint8
    d200::Uint8
    d201::Uint8
    d202::Uint8
    d203::Uint8
    d204::Uint8
    d205::Uint8
    d206::Uint8
    d207::Uint8
    d208::Uint8
    d209::Uint8
    d210::Uint8
    d211::Uint8
    d212::Uint8
    d213::Uint8
    d214::Uint8
    d215::Uint8
    d216::Uint8
    d217::Uint8
    d218::Uint8
    d219::Uint8
    d220::Uint8
    d221::Uint8
    d222::Uint8
    d223::Uint8
    d224::Uint8
    d225::Uint8
    d226::Uint8
    d227::Uint8
    d228::Uint8
    d229::Uint8
    d230::Uint8
    d231::Uint8
    d232::Uint8
    d233::Uint8
    d234::Uint8
    d235::Uint8
    d236::Uint8
    d237::Uint8
    d238::Uint8
    d239::Uint8
    d240::Uint8
    d241::Uint8
    d242::Uint8
    d243::Uint8
    d244::Uint8
    d245::Uint8
    d246::Uint8
    d247::Uint8
    d248::Uint8
    d249::Uint8
    d250::Uint8
    d251::Uint8
    d252::Uint8
    d253::Uint8
    d254::Uint8
    d255::Uint8
    d256::Uint8
end

zero(::Type{Array_256_Uint8}) = Array_256_Uint8(fill(zero(Uint8),256)...)

immutable Array_3_Cint
    d1::Cint
    d2::Cint
    d3::Cint
end

zero(::Type{Array_3_Cint}) = Array_3_Cint(fill(zero(Cint),3)...)

immutable Array_2_Cint
    d1::Cint
    d2::Cint
end

zero(::Type{Array_2_Cint}) = Array_2_Cint(fill(zero(Cint),2)...)

immutable cudaDeviceProp
    name::Array_256_Uint8
    totalGlobalMem::Csize_t
    sharedMemPerBlock::Csize_t
    regsPerBlock::Cint
    warpSize::Cint
    memPitch::Csize_t
    maxThreadsPerBlock::Cint
    maxThreadsDim::Array_3_Cint
    maxGridSize::Array_3_Cint
    clockRate::Cint
    totalConstMem::Csize_t
    major::Cint
    minor::Cint
    textureAlignment::Csize_t
    texturePitchAlignment::Csize_t
    deviceOverlap::Cint
    multiProcessorCount::Cint
    kernelExecTimeoutEnabled::Cint
    integrated::Cint
    canMapHostMemory::Cint
    computeMode::Cint
    maxTexture1D::Cint
    maxTexture1DMipmap::Cint
    maxTexture1DLinear::Cint
    maxTexture2D::Array_2_Cint
    maxTexture2DMipmap::Array_2_Cint
    maxTexture2DLinear::Array_3_Cint
    maxTexture2DGather::Array_2_Cint
    maxTexture3D::Array_3_Cint
    maxTexture3DAlt::Array_3_Cint
    maxTextureCubemap::Cint
    maxTexture1DLayered::Array_2_Cint
    maxTexture2DLayered::Array_3_Cint
    maxTextureCubemapLayered::Array_2_Cint
    maxSurface1D::Cint
    maxSurface2D::Array_2_Cint
    maxSurface3D::Array_3_Cint
    maxSurface1DLayered::Array_2_Cint
    maxSurface2DLayered::Array_3_Cint
    maxSurfaceCubemap::Cint
    maxSurfaceCubemapLayered::Array_2_Cint
    surfaceAlignment::Csize_t
    concurrentKernels::Cint
    ECCEnabled::Cint
    pciBusID::Cint
    pciDeviceID::Cint
    pciDomainID::Cint
    tccDriver::Cint
    asyncEngineCount::Cint
    unifiedAddressing::Cint
    memoryClockRate::Cint
    memoryBusWidth::Cint
    l2CacheSize::Cint
    maxThreadsPerMultiProcessor::Cint
    streamPrioritiesSupported::Cint
    globalL1CacheSupported::Cint
    localL1CacheSupported::Cint
    sharedMemPerMultiprocessor::Csize_t
    regsPerMultiprocessor::Cint
    managedMemory::Cint
    isMultiGpuBoard::Cint
    multiGpuBoardGroupID::Cint
end

immutable Array_64_Uint8
    d1::Uint8
    d2::Uint8
    d3::Uint8
    d4::Uint8
    d5::Uint8
    d6::Uint8
    d7::Uint8
    d8::Uint8
    d9::Uint8
    d10::Uint8
    d11::Uint8
    d12::Uint8
    d13::Uint8
    d14::Uint8
    d15::Uint8
    d16::Uint8
    d17::Uint8
    d18::Uint8
    d19::Uint8
    d20::Uint8
    d21::Uint8
    d22::Uint8
    d23::Uint8
    d24::Uint8
    d25::Uint8
    d26::Uint8
    d27::Uint8
    d28::Uint8
    d29::Uint8
    d30::Uint8
    d31::Uint8
    d32::Uint8
    d33::Uint8
    d34::Uint8
    d35::Uint8
    d36::Uint8
    d37::Uint8
    d38::Uint8
    d39::Uint8
    d40::Uint8
    d41::Uint8
    d42::Uint8
    d43::Uint8
    d44::Uint8
    d45::Uint8
    d46::Uint8
    d47::Uint8
    d48::Uint8
    d49::Uint8
    d50::Uint8
    d51::Uint8
    d52::Uint8
    d53::Uint8
    d54::Uint8
    d55::Uint8
    d56::Uint8
    d57::Uint8
    d58::Uint8
    d59::Uint8
    d60::Uint8
    d61::Uint8
    d62::Uint8
    d63::Uint8
    d64::Uint8
end

zero(::Type{Array_64_Uint8}) = Array_64_Uint8(fill(zero(Uint8),64)...)

immutable cudaIpcEventHandle_st
    reserved::Array_64_Uint8
end

immutable cudaIpcEventHandle_t
    reserved::Array_64_Uint8
end

immutable cudaIpcMemHandle_st
    reserved::Array_64_Uint8
end

immutable cudaIpcMemHandle_t
    reserved::Array_64_Uint8
end

typealias cudaError_t cudaError
typealias CUstream_st Void
typealias cudaStream_t Ptr{CUstream_st}
typealias CUevent_st Void
typealias cudaEvent_t Ptr{CUevent_st}
typealias cudaGraphicsResource_t Ptr{cudaGraphicsResource}
typealias CUuuid_st Void
typealias cudaUUID_t Void
typealias cudaOutputMode_t cudaOutputMode

immutable char1
    x::Uint8
end

immutable uchar1
    x::Cuchar
end

immutable char3
    x::Uint8
    y::Uint8
    z::Uint8
end

immutable uchar3
    x::Cuchar
    y::Cuchar
    z::Cuchar
end

immutable short1
    x::Int16
end

immutable ushort1
    x::Uint16
end

immutable short3
    x::Int16
    y::Int16
    z::Int16
end

immutable ushort3
    x::Uint16
    y::Uint16
    z::Uint16
end

immutable int1
    x::Cint
end

immutable uint1
    x::Uint32
end

immutable int3
    x::Cint
    y::Cint
    z::Cint
end

immutable uint3
    x::Uint32
    y::Uint32
    z::Uint32
end

immutable long1
    x::Clong
end

immutable ulong1
    x::Culong
end

immutable long3
    x::Clong
    y::Clong
    z::Clong
end

immutable ulong3
    x::Culong
    y::Culong
    z::Culong
end

immutable float1
    x::Cfloat
end

immutable float3
    x::Cfloat
    y::Cfloat
    z::Cfloat
end

immutable longlong1
    x::Clonglong
end

immutable ulonglong1
    x::Culonglong
end

immutable longlong3
    x::Clonglong
    y::Clonglong
    z::Clonglong
end

immutable ulonglong3
    x::Culonglong
    y::Culonglong
    z::Culonglong
end

immutable double1
    x::Cdouble
end

immutable double3
    x::Cdouble
    y::Cdouble
    z::Cdouble
end

immutable dim3
    x::Uint32
    y::Uint32
    z::Uint32
end

const CUDART_VERSION = 6050

()

typealias cudaStreamCallback_t Ptr{Void}


text:
# var/distances.jl
# ==================
#
# Types and methods for computing evolutionary and genetic distances.
#
# Part of the Bio.Var module.
#
# This file is a part of BioJulia. License is MIT: https://github.com/BioJulia/Bio.jl/blob/master/LICENSE.md

# Types
# -----

abstract EvolutionaryDistance
abstract UncorrectedDistance <: EvolutionaryDistance
abstract CorrectedDistance <: EvolutionaryDistance
abstract TsTv <: CorrectedDistance

"""
A distance which is the count of the mutations of type T that exist between the
two sequences.
"""
immutable Count{T} <: UncorrectedDistance end

"""
Proportion{T} is a distance which is the count of the mutations of type T that
exist between the two biological sequences, divided by the number of valid sites
examined (sites which don't have gap or ambiguous symbols).

In other words this so called p-distance is simply the proportion of sites
between each pair of sequences, that are mutated (again where T determines
what kind of mutation).
"""
immutable Proportion{T} <: UncorrectedDistance end

"""
The JukesCantor69 distance is a p-distance adjusted/corrected by the
substitution model developed by Jukes and Cantor in 1969.

The Jukes and Cantor model assumes that all substitutions
(i.e. a change of a base by another one) have the same probability.
This probability is the same for all sites along the DNA sequence.
"""
immutable JukesCantor69 <: CorrectedDistance end

"""
The Kimura80 distance uses a substitution model developed by Kimura in 1980.
It is somtimes called Kimura's 2 parameter distance.

The model makes the same assumptions as Jukes and Cantor's model, but with a
crucial difference: two-kinds of mutation are considered
called Transitions and Transversions.
Transitions and transversions can occur with different probabilities in this
model, however, both transition and transversion rates/probabilities are the
same for all sites along the DNA sequence.
"""
immutable Kimura80 <: TsTv end

# Distance computation internals
# ------------------------------

@inline function expected_distance{T}(::Type{Proportion{T}}, n::Int64, l::Int64)
    return n / l
end

## Jukes and Cantor 1969 distance computation.

@inline function expected_distance(::Type{JukesCantor69}, p::Float64)
    return -0.75 * log(1 - 4 * p / 3)
end

@inline function variance(::Type{JukesCantor69}, p::Float64, l::Int64)
    return p * (1 - p) / (((1 - 4 * p / 3) ^ 2) * l)
end

## Kimura80 Distance computation internals

@inline function expected_distance(::Type{Kimura80}, a1::AbstractFloat, a2::AbstractFloat)
    return -0.5 * log(a1 * sqrt(a2))
end

@inline function expected_distance(::Type{Kimura80}, a1::AbstractFloat, a2::AbstractFloat,
    gamma::AbstractFloat)
    b = -1 / alpha
    return alpha * ((a1 ^ b) + 0.5 * (a2 ^ b) - 1.5) / 2
end

macro Kimura80var()
    :(return ((c1 * c1 * P + c3 * c3 * Q) - ((c1 * P + c3 * Q) ^ 2)) / L)
end

@inline function variance(::Type{Kimura80}, P::AbstractFloat, Q::AbstractFloat, L::Int, a1::AbstractFloat,
    a2::AbstractFloat)
    c1 = 1 / a1
    c2 = 1 / a2
    c3 = (c1 + c2) / 2
    @Kimura80var
end

@inline function variance(::Type{Kimura80}, P::AbstractFloat, Q::AbstractFloat, L::Int, a1::AbstractFloat,
    a2::AbstractFloat, gamma::AbstractFloat)
    b = -(1 / gamma + 1)
    c1 = a1 ^ b
    c2 = a2 ^ b
    c3 = (c1 + c2) / 2
    @Kimura80var
end

# Distance computation methods
# ----------------------------

"""
Compute the pairwise genetic distances for a set of aligned nucleotide sequences.

The distance measure to compute is determined by the type provided as the first
parameter. The second parameter provides the set of nucleotide sequences.
"""
function distance end

"""
    distance{T<:MutationType,A<:NucleotideAlphabet}(::Type{Count{T}}, seqs::Vector{BioSequence{A}})

Compute the number of mutations of type `T` between a set of sequences in a
pairwise manner.

This method of distance returns a tuple of the number of mutations of type `T`
between sequences and the number of valid (i.e. non-ambiguous sites) counted by
the function.
"""
function distance{T<:MutationType,A<:NucleotideAlphabet}(::Type{Count{T}}, seqs::Vector{BioSequence{A}})
    return count_mutations(T, seqs)
end

"""
    distance{T<:MutationType,A<:NucleotideAlphabet}(::Type{Count{T}}, seqs::Vector{BioSequence{A}}, width::Int, step::Int)

Compute pairwise distances using a sliding window.

As the window of `width` base pairs in size moves across a pair of sequences it
computes the distance between the two sequences in that window.

This method computes mutation counts for every window, and returns a tuple of the
matrix of p-distances for every window, a matrix of the number of valid sites
counted by the function for each window.
"""
function distance{T<:MutationType,A<:NucleotideAlphabet}(::Type{Count{T}}, seqs::Vector{BioSequence{A}}, width::Int, step::Int)
    mutation_flags, ambiguous_flags = flagmutations(T, seqs)
    nbases, npairs = size(mutation_flags)
    if width < 1
        throw(ArgumentError("`window` width must be ≥ 1."))
    end
    if step < 1
        throw(ArgumentError("`step` must be ≥ 1."))
    end
    if width > nbases
        throw(ArgumentError("The `window` size cannot be greater than number of data elements."))
    end
    starts = 1:step:nbases
    ends = width:step:nbases
    nwindows = length(ends)
    mcounts = Matrix{Int}(nwindows, npairs)
    wsizes = Matrix{Int}(nwindows, npairs)
    ranges = Vector{UnitRange{Int}}(nwindows)

    @inbounds for pair in 1:npairs
        pairoffset = pair - 1
        windowoffset = pairoffset * nwindows
        flagsoffset = pairoffset * nbases
        for i in 1:nwindows
            from = starts[i]
            to = ends[i]
            mcount = 0
            nsites = width
            @simd for j in from:to
                mcount += mutation_flags[flagsoffset + j]
                nsites -= ambiguous_flags[flagsoffset + j]
            end
            ranges[i] = UnitRange(starts[i],ends[i])
            mcounts[windowoffset + i] = mcount
            wsizes[windowoffset + i] = nsites
        end
    end
    return mcounts, wsizes, ranges
end

function distance{T<:TsTv,A<:NucleotideAlphabet}(::Type{Count{T}}, seqs::Vector{BioSequence{A}}, width::Int, step::Int)
    transitionFlags, transversionFlags, ambiguous_flags = flagmutations(TransitionMutation, TransversionMutation, seqs)
    nbases, npairs = size(transitionFlags)
    if width < 1
        throw(ArgumentError("`window` width must be ≥ 1."))
    end
    if step < 1
        throw(ArgumentError("`step` must be ≥ 1."))
    end
    if width > nbases
        throw(ArgumentError("The `window` size cannot be greater than number of data elements."))
    end
    starts = 1:step:nbases
    ends = width:step:nbases
    nwindows = length(ends)
    tscounts = Matrix{Int}(nwindows, npairs)
    tvcounts = Matrix{Int}(nwindows, npairs)
    wsizes = Matrix{Int}(nwindows, npairs)
    ranges = Vector{UnitRange{Int}}(nwindows)

    @inbounds for pair in 1:npairs
        pairoffset = pair - 1
        windowoffset = pairoffset * nwindows
        flagsoffset = pairoffset * nbases
        for i in 1:nwindows
            from = starts[i]
            to = ends[i]
            tscount = 0
            tvcount = 0
            nsites = width
            @simd for j in from:to
                tscount += transitionFlags[flagsoffset + j]
                tvcount += transversionFlags[flagsoffset + j]
                nsites -= ambiguous_flags[flagsoffset + j]
            end
            ranges[i] = UnitRange(starts[i],ends[i])
            tscounts[windowoffset + i] = tscount
            tvcounts[windowoffset + i] = tvcount
            wsizes[windowoffset + i] = nsites
        end
    end
    return tscounts, tvcounts, wsizes, ranges
end

"""
    distance{T<:MutationType,N<:Nucleotide}(::Type{Count{T}}, seqs::Matrix{N})

Compute the number of mutations of type `T` between a set of sequences in a
pairwise manner.

This method of distance returns a tuple of the number of mutations of type `T`
between sequences and the number of valid (i.e. non-ambiguous sites) counted by
the function.

**Note: This method assumes that the sequences are stored in the `Matrix{N}`
provided as `seqs` in sequence major order i.e. each column of the matrix is one
complete nucleotide sequence.**
"""
function distance{T<:MutationType,N<:Nucleotide}(::Type{Count{T}}, seqs::Matrix{N})
    return count_mutations(T, seqs)
end

function distance{T<:TsTv,A<:NucleotideAlphabet}(::Type{Count{T}}, seqs::Vector{BioSequence{A}})
    return count_mutations(TransitionMutation, TransversionMutation, seqs)
end

function distance{T<:TsTv,N<:Nucleotide}(::Type{Count{T}}, seqs::Matrix{N})
    return count_mutations(TransitionMutation, TransversionMutation, seqs)
end

"""
    distance{T<:MutationType,A<:NucleotideAlphabet}(::Type{Proportion{T}}, seqs::Vector{BioSequence{A}})

This method of distance returns a tuple of a vector of the p-distances, and a
vector of the number of valid (i.e. non-ambiguous sites) counted by the function.
"""
function distance{T<:MutationType,A<:NucleotideAlphabet}(::Type{Proportion{T}}, seqs::Vector{BioSequence{A}})
    d, l = distance(Count{T}, seqs)
    D = Vector{Float64}(length(d))
    @inbounds @simd for i in 1:length(D)
        D[i] = d[i] / l[i]
    end
    return D, l
end

"""
    distance{T<:MutationType,N<:Nucleotide}(::Type{Proportion{T}}, seqs::Matrix{N})

This method of distance returns a tuple of a vector of the p-distances, and a
vector of the number of valid (i.e. non-ambiguous) sites counted by the function.

**Note: This method assumes that the sequences are stored in the `Matrix{N}`
provided as `seqs` in sequence major order i.e. each column of the matrix is one
complete nucleotide sequence.**
"""
function distance{T<:MutationType,N<:Nucleotide}(::Type{Proportion{T}}, seqs::Matrix{N})
    d, l = distance(Count{T}, seqs)
    D = Vector{Float64}(length(d))
    @inbounds for i in 1:length(D)
        D[i] = d[i] / l[i]
    end
    return D, l
end

"""
    distance{T<:MutationType,A<:NucleotideAlphabet}(::Type{Proportion{T}}, seqs::Vector{BioSequence{A}}, width::Int, step::Int)

A distance method which computes pairwise distances using a sliding window.

As the window of `width` base pairs in size moves across a pair of sequences it
computes the distance between the two sequences in that window.

This method computes p-distances for every window, and returns a tuple of the
matrix of p-distances for every window, a matrix of the number of valid sites
counted by the function for each window.
"""
function distance{T<:MutationType,A<:NucleotideAlphabet}(::Type{Proportion{T}}, seqs::Vector{BioSequence{A}}, width::Int, step::Int)
    counts, wsizes, ranges = distance(Count{T}, seqs, width, step)
    res = Matrix{Float64}(size(counts))
    @inbounds for i in 1:endof(counts)
        res[i] = expected_distance(Proportion{T}, counts[i], wsizes[i])
    end
    return res, wsizes, ranges
end

"""
    distance{A<:NucleotideAlphabet}(::Type{JukesCantor69}, seqs::Vector{BioSequence{A}})

This method of distance returns a tuple of the expected JukesCantor69 distance
estimate, and the computed variance.
"""
function distance{A<:NucleotideAlphabet}(::Type{JukesCantor69}, seqs::Vector{BioSequence{A}})
    p, l = distance(Proportion{AnyMutation}, seqs)
    D = Vector{Float64}(length(p))
    V = Vector{Float64}(length(p))
    @inbounds for i in 1:length(p)
        D[i] = expected_distance(JukesCantor69, p[i])
        V[i] = variance(JukesCantor69, p[i], l[i])
    end
    return D, V
end

"""
    distance{T<:MutationType,A<:NucleotideAlphabet}(::Type{JukesCantor69}, seqs::Vector{BioSequence{A}}, width::Int, step::Int)

A distance method which computes pairwise distances using a sliding window.

As the window of `width` base pairs in size moves across a pair of sequences it
computes the distance between the two sequences in that window.

This method computes the JukesCantor69 distance for every window, and returns a tuple of the
matrix of p-distances for every window, a matrix of the number of valid sites
counted by the function for each window.
"""
function distance{A<:NucleotideAlphabet}(::Type{JukesCantor69}, seqs::Vector{BioSequence{A}}, width::Int, step::Int)
    ps, wsizes, ranges = distance(Proportion{AnyMutation}, seqs, width, step)
    a, b = size(ps)
    est = Matrix{Float64}(a, b)
    var = Matrix{Float64}(a, b)
    @inbounds for i in 1:endof(ps)
        p = ps[i]
        l = wsizes[i]
        est[i] = expected_distance(JukesCantor69, p)
        var[i] = variance(JukesCantor69, p, l)
    end
    return est, var, ranges
end

"""
    distance{N<:Nucleotide}(::Type{JukesCantor69}, seqs::Matrix{N})

This method of distance returns a tuple of the expected JukesCantor69 distance
estimate, and the computed variance.

**Note: This method assumes that the sequences are stored in the `Matrix{N}`
provided as `seqs` in sequence major order i.e. each column of the matrix is one
complete nucleotide sequence.**
"""
function distance{N<:Nucleotide}(::Type{JukesCantor69}, seqs::Matrix{N})
    p, l = distance(Proportion{AnyMutation}, seqs)
    D = Vector{Float64}(length(p))
    V = Vector{Float64}(length(p))
    @inbounds for i in 1:length(p)
        D[i] = expected_distance(JukesCantor69, p[i])
        V[i] = variance(JukesCantor69, p[i], l[i])
    end
    return D, V
end

"""
    distance{A<:NucleotideAlphabet}(::Type{Kimura80}, seqs::Vector{BioSequence{A}})

This method of distance returns a tuple of the expected Kimura80 distance
estimate, and the computed variance.
"""
function distance{A<:NucleotideAlphabet}(::Type{Kimura80}, seqs::Vector{BioSequence{A}})
    ns, nv, l = distance(Count{Kimura80}, seqs)
    D = Vector{Float64}(length(ns))
    V = Vector{Float64}(length(ns))
    @inbounds for i in 1:length(ns)
        L = l[i]
        P = ns[i] / L
        Q = nv[i] / L
        a1 = 1 - 2 * P - Q
        a2 = 1 - 2 * Q
        D[i] = expected_distance(Kimura80, a1, a2)
        V[i] = variance(Kimura80, P, Q, L, a1, a2)
    end
    return D, V
end

"""
    distance{T<:MutationType,A<:NucleotideAlphabet}(::Type{Kimura80}, seqs::Vector{BioSequence{A}}, width::Int, step::Int)

A distance method which computes pairwise distances using a sliding window.

As the window of `width` base pairs in size moves across a pair of sequences it
computes the distance between the two sequences in that window.

This method computes the Kimura80 distance for every window, and returns a tuple of the
matrix of p-distances for every window, a matrix of the number of valid sites
counted by the function for each window.
"""
function distance{A<:NucleotideAlphabet}(::Type{Kimura80}, seqs::Vector{BioSequence{A}}, width::Int, step::Int)
    tss, tvs, wsizes, ranges = distance(Count{Kimura80}, seqs, width, step)
    a, b = size(tss)
    est = Matrix{Float64}(a, b)
    var = Matrix{Float64}(a, b)
    @inbounds for i in 1:endof(counts)
        L = l[i]
        P = tss[i] / L
        Q = tvs[i] / L
        a1 = 1 - 2 * P - Q
        a2 = 1 - 2 * Q
        tv = tvs[i]
        l = wsizes[i]
        est[i] = expected_distance(Kimura80, a1, a2)
        var[i] = variance(Kimura80, P, Q, L, a1, a2)
    end
    return est, var, ranges
end

"""
    distance{N<:Nucleotide}(::Type{Kimura80}, seqs::Matrix{N})

This method of distance returns a tuple of the expected Kimura80 distance
estimate, and the computed variance.

**Note: This method assumes that the sequences are stored in the `Matrix{N}`
provided as `seqs` in sequence major order i.e. each column of the matrix is one
complete nucleotide sequence.**
"""
function distance{N<:Nucleotide}(::Type{Kimura80}, seqs::Matrix{N})
    ns, nv, l = distance(Count{Kimura80}, seqs)
    D = Vector{Float64}(length(ns))
    V = Vector{Float64}(length(ns))
    @inbounds for i in 1:length(ns)
        L = l[i]
        P = ns[i] / L
        Q = nv[i] / L
        a1 = 1 - 2 * P - Q
        a2 = 1 - 2 * Q
        D[i] = expected_distance(Kimura80, a1, a2)
        V[i] = variance(Kimura80, P, Q, L, a1, a2)
    end
    return D, V
end

ext: jl


text:
using BlackBoxOptim

require("../covar_matrix_self_adaptation_es.jl")
require("../experiment_framework.jl")
require("../../src/experiments/parameter_experiment.jl")

n = 8
p = as_fixed_dim_problem(BlackBoxOptim.example_problems["Rosenbrock"], n)
p = BlackBoxOptim.shifted(p)
diameter = minimum(diameters(search_space(p)))

pe = cmsa_es_exp2 = ParameterExperiment(
  ["covar_learning_rate", "sigma", "lambda", "mu",
    "covarMatrixSampler", "utilitiesFunc"
  ],
  [((ds, ps) -> ds[1]),
   ((ds, ps) -> diameter * 10^ds[2]),
   ((ds, ps) -> int(round(ds[3]))),
   ((ds, ps) -> int(max(1.0, ceil(ps[3] / ds[4])))),
   ((ds, ps) -> ds[5] < 0.5 ? EigenCovarSampler : CholeskyCovarSampler),
   ((ds, ps) -> ds[6] < 0.5 ? linear_utilities : log_utilities)
  ],
  [( 0.6, 1.0),
   (-2.0, 0.0),
   ( 8.0, float(n*n)),
   ( 2.0, 8.0),
   ( 0.0, 1.0),
   ( 0.0, 1.0)
  ]
)

# It seems clear that (in order of sensitivity)
#  1. covar_learning_rate needs to be high (highest sensitivity)
#  2. mu should be a rather high divisor, at least 4, maybe even 8
#  3. we should use log_utilities (but large variation on this one so unclear)
#  4. sigma should be rather low (but low sensitivity)
#  5. lambda should be high, rather than low (low s)
#  6. the covar sampler does not have a large effect but Cholesky seems somewhat better
#
# We design a new experiment in line with this:

pe3 = cmsa_es_exp3 = ParameterExperiment(
  ["covar_learning_rate", "sigma", "lambda", "mu",
  ],
  [((ds, ps) -> ds[1]),
   ((ds, ps) -> diameter * 10^ds[2]),
   ((ds, ps) -> int(round(ds[3]))),
   ((ds, ps) -> int(max(1.0, ceil(ps[3] / ds[4]))))
  ],
  [( 0.75, 1.0),
   (-4.0, -1.0),
   (float(4*n), float(4*n*n)),
   ( 3.0, 16.0)
  ]
)

# There is quite a lot of variation for all of these covariates, except for
# low values of covariate 1 but conclusions are:
#   1. mu divisor should be larger than 5.6 (3+(16-3)*0.20) and higher values seem to be good
#   2. lambda should be between 0.10-0.35 of the range 4*n to 4*n*n
#   3. covar_learning_rate should be between 0.35-0.60 of the range 0.75-1.0 so in range 0.84-0.90
#   4. sigma should be 0.80-1.0 in its range so 10^[-2, -1] of diameter with higher values giving quicker responses.

# Based on these 2 experiments (exp2 and exp3) we conclude that:
#   1. covar_learning_rate should be in 0.85-0.90
#   2. lambda should be circa 4*n+.20*(4*n*n - 4*n)
#   3. mu divisor should be in 5-16
#   4. sigma should be 0.01-0.10 of the diameter
# Lets now try these settings on the Rosenbrock with 16 dims.

n = 16
p = as_fixed_dim_problem(BlackBoxOptim.example_problems["Rosenbrock"], n)
p = BlackBoxOptim.shifted(p)
diameter = minimum(diameters(search_space(p)))

pe4 = cmsa_es_exp4 = ParameterExperiment(
  ["covar_learning_rate", "sigma", "lambda", "mu",
  ],
  [((ds, ps) -> ds[1]),
   ((ds, ps) -> diameter * 10^ds[2]),
   ((ds, ps) -> int(round(ds[3]))),
   ((ds, ps) -> int(max(1.0, ceil(ps[3] / ds[4]))))
  ],
  [( 0.84, 0.99),
   (-2.0, -0.5),
   (float(4*n), float(4*n*n)),
   ( 5.0, 20.0)
  ]
)

outfile = "cmsa_es_exp4.csv"
write_csv_header_to_file(pe4, outfile)

# Optimize to minimize the fail rate, i.e. inverted success rate:
# /usr/bin/Rscript ../../R/parameter_experiment.R 4 5 -11 4 cmsa_es_exp4.csv new_runs.json

run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(pe4, outfile, 5; num_repeats = 5)

# /usr/bin/Rscript ../../R/parameter_experiment.R 4 5 -11 4 cmsa_es_exp4.csv new_runs.json

# For Rosenbrock 16 we saw good performance for the same param values as for
# the 8-d version. In detail we conclude:
#   1. best performance for lambda closer to 4*n than higher (highest sens)
#   2. best performance for low mu all the way down to divisor 20 (high sens)
#   3. covar learning rate should be from around 0.89-0.95 but worse if higher
#   4. fairly insensitive to sigma as long as its around 0.05-0.20 of diameter (lowest sens)
#
# Lets now try these settings on the Rosenbrock with 32 dims.

n = 32
p = as_fixed_dim_problem(BlackBoxOptim.example_problems["Rosenbrock"], n)
p = BlackBoxOptim.shifted(p)
diameter = minimum(diameters(search_space(p)))

pe5 = ParameterExperiment(
  ["covar_learning_rate", "sigma", "lambda", "mu",
  ],
  [((ds, ps) -> ds[1]),
   ((ds, ps) -> diameter * 10^ds[2]),
   ((ds, ps) -> int(round(ds[3]))),
   ((ds, ps) -> int(max(1.0, ceil(ps[3] / ds[4]))))
  ],
  [( 0.84, 0.99),
   (-2.0, -0.5),
   (float(2*n), float(2*n*n)),
   ( 5.0, 25.0)
  ]
)

outfile = "cmsa_es_exp5.csv"
write_csv_header_to_file(pe5, outfile)

# /usr/bin/Rscript ../../R/parameter_experiment.R 4 5 -11 4 cmsa_es_exp5.csv new_runs.json

run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(pe5, outfile, 5; num_repeats = 5)

# Meta-strategy: Not good to run 5 initial runs and then do 25 ones based on EI =>
# only 10% or so for n=32 had high success rate. This is in line with common sense, i.e.
# when doing adaptive sampling one should do it in very small batches (1 run at a time)
# to learn as much as possible about the response before each run).

# For Rosenbrock 32 we saw good performance but for somewhat different values than
# for 8 and 16:
# After 35 runs:
# best: {:covar_learning_rate=>0.9851933684393066,:lambda=>331,:sigma=>0.937811910301762,:mu=>15}
# top5_max: {:covar_learning_rate=>0.9860690669022734,:lambda=>501,:sigma=>2.650768642586489,:mu=>22}
# top5_mean: {:covar_learning_rate=>0.9822724531856971,:lambda=>344,:sigma=>1.4712605685842668,:mu=>18}
# top5_min: {:covar_learning_rate=>0.9780927470649825,:lambda=>168,:sigma=>0.8147138415085076,:mu=>12}
#
#   1. best performance for lambda around 5*n to 15*n but better with lower (highest sens)
#   2. covar learning rate should be from around 0.97-0.98 (high sens)
#   3. best performance for low mu all the way down to divisor 20 (lower sens)
#   4. fairly insensitive to sigma as long as its around 0.02-0.07 of diameter (lowest sens)

# Before addressing Rosenbrock 64-D we added stopping if no progress in 1000*lambda
# func evals (for cmsa_es). I also fixed a bug in the cmsa_es code so that the sigma
# does not increase indefinetely to compensate for bad scaling of the covar matrix update.
# Because of this we also changed back to the tau equations of Beyer et al.
# And added a probability for decomposing the covar, to save time. But it might affect quality.
# So I guess I might need to have to rerun all experiments... ;)

n = 64
p = as_fixed_dim_problem(BlackBoxOptim.example_problems["Rosenbrock"], n)
p = BlackBoxOptim.shifted(p)
diameter = minimum(diameters(search_space(p)))

pe6 = ParameterExperiment(
  ["tau", "lambda", "mu", "tau_c", "sigma", "decompose_covar_prob"
  ],
  [((ds, ps) -> (2*n)^ds[1]),
   ((ds, ps) -> n*int(round(ds[2]))),
   ((ds, ps) -> int(max(1.0, ceil(ps[2] / ds[3])))),
   ((ds, ps) -> 1 + n * (n+1) / (ds[4]*ps[3])),
   ((ds, ps) -> diameter * 10^ds[5]),
   ((ds, ps) -> ds[6])
  ],
  [(-2.0, 0.0),
   ( 1.0, float(n)),
   ( 4.0, 20.0),
   (0.01, 3.0),
   (-3.0, 0.0),
   (0.01, 1.0)
  ]
)

# First we minimize the magnitude class with ei => 14
outfile = "cmsa_es_exp6.csv"
write_csv_header_to_file(pe6, outfile)
run(`/usr/bin/Rscript ../../R/parameter_experiment.R 6 7 14 6 $(outfile) new_runs.json`)
run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe6, outfile; num_repeats = 1)
for i in 1:33
  run(`/usr/bin/Rscript ../../R/parameter_experiment.R 6 1 14 6 $(outfile) new_runs.json sa min`)
  run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe6, outfile; num_repeats = 2)
end
# Then we maximize the success rate and select the quickest among the top 10.
for i in 1:10
  run(`/usr/bin/Rscript ../../R/parameter_experiment.R 6 1 14 6 $(outfile) new_runs.json sa minquick`)
  run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe6, outfile; num_repeats = 2)
end

# Conclusions for finding good solutions (in sensitivity order):
#  1. lambda should be a fairly low multiple of n, 1-8
#  2. values of tau seem influential but lots of variation in its effect so hard to give guidance => fix to theoretic value!?
#  3. tau_c fairly influential and should probably be a divisor of 3*mu rather than 2*mu => fix to 2*mu?
#  4. mu somewhat influential and should rather be a high than a low divisor, maybe in range 8-20 rather than 4-8 of lambda.
#  5. decompose_covar_prob not so influential on its own but interacts with the others higher values seems generally somewhat better, but not strongly and affects time behavior.
#  6. sigma not so important but rather higher (1*diameter) than lower (0.001*diameter)

# Lets do a final Rosenbrock 128-D before going on to other problems.

n = 128
p = as_fixed_dim_problem(BlackBoxOptim.example_problems["Rosenbrock"], n)
p = BlackBoxOptim.shifted(p)
diameter = minimum(diameters(search_space(p)))

pe7 = ParameterExperiment(
  ["lambda", "mu", "sigma", "decompose_covar_prob"
  ],
  [((ds, ps) -> int(round(n*ds[1]))),
   ((ds, ps) -> int(max(1.0, ceil(ps[1] / ds[2])))),
   ((ds, ps) -> diameter * 10^ds[3]),
   ((ds, ps) -> ds[4])
  ],
  [( 0.5, float(n)),
   ( 4.0, 20.0),
   (-2.0, 0.0),
   (0.01, 1.0)
  ]
)

outfile = "cmsa_es_exp7.csv"
write_csv_header_to_file(pe7, outfile)
run(`/usr/bin/Rscript ../../R/parameter_experiment.R 4 5 10 4 $(outfile) new_runs.json`)
run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe7, outfile; num_repeats = 1)

# It seems that covergence is slow. I posit that this may be because of mu being too high =>
# increase size of max divisor in experiments.
# We also try to reduce the decompose_covar_prob max value since the cost of
# decomposing the covar matrix is high for high-dimensional problems.

pe8 = ParameterExperiment(
  ["lambda", "mu", "sigma", "decompose_covar_prob"
  ],
  [((ds, ps) -> int(round(n*ds[1]))),
   ((ds, ps) -> int(max(1.0, ceil(ps[1] / ds[2])))),
   ((ds, ps) -> diameter * 10^ds[3]),
   ((ds, ps) -> ds[4])
  ],
  [( 0.1, float(n)),
   ( 6.0, float(n)),
   (-2.0, 0.0),
   (0.01, 0.50)
  ]
)

outfile = "cmsa_es_exp8.csv"
write_csv_header_to_file(pe8, outfile)
run(`/usr/bin/Rscript ../../R/parameter_experiment.R 4 5 10 4 $(outfile) new_runs.json`)
run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe8, outfile; num_repeats = 1)
# Since many runs end up in the 2.0 magnitude class we optimize on fitness rather than magnitude => higher resolution.
# First we minimize the magnitude class with ei => 2*4+1
for i in 1:20
  run(`/usr/bin/Rscript ../../R/parameter_experiment.R 4 1 9 4 $(outfile) new_runs.json sa ei`)
  run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe8, outfile; num_repeats = 1)
end

# It seems hard to make progress on this one and it seems that very low values for lambda
# and mu are needed. So lets expand the search ranges and add back the old tau_c and tau
# covariates and lets see what we find.

pe9 = ParameterExperiment(
  ["lambda", "mu", "sigma", "decompose_covar_prob", "tau", "tau_c"
  ],
  [((ds, ps) -> int(10^ds[1])),
   ((ds, ps) -> int(max(1.0, ds[2]*ps[1]))),
   ((ds, ps) -> diameter * 10^ds[3]),
   ((ds, ps) -> ds[4]),
   ((ds, ps) -> (2*n)^ds[5]),
   ((ds, ps) -> 1 + n * (n+1) / (ds[6]*ps[2]))
  ],
  [( log10(4.0 + log(n)), log10(n*n)),
   ( 0.0, 1/4),
   (-3.0, 0.0),
   (0.01, 0.50),
   (-2.0, 0.0),
   (1.0,  6.0)
  ]
)
outfile = "cmsa_es_exp9.csv"
write_csv_header_to_file(pe9, outfile)
run(`/usr/bin/Rscript ../../R/parameter_experiment.R 6 7 14 6 $(outfile) new_runs.json`)
run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe9, outfile; num_repeats = 1)
for i in 1:23
  run(`/usr/bin/Rscript ../../R/parameter_experiment.R 6 1 14 6 $(outfile) new_runs.json sa ei`)
  run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe9, outfile; num_repeats = 1)
end
# Then we maximize the success rate and select the quickest among the top 10.
for i in 1:3
  run(`/usr/bin/Rscript ../../R/parameter_experiment.R 6 1 15 6 $(outfile) new_runs.json sa min`)
  run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe9, outfile; num_repeats = 1)
end

pe10 = ParameterExperiment(
  ["lambda", "mu", "sigma", "decompose_covar_prob",
   "max_successes_before_increasing", "max_failures_before_decreasing", "max_rounds_without_improvement"
  ],
  [((ds, ps) -> int(10^ds[1])),
   ((ds, ps) -> int(max(1.0, ds[2]*ps[1]))),
   ((ds, ps) -> diameter * 10^ds[3]),
   ((ds, ps) -> ds[4]),
   ((ds, ps) -> int(ds[5])),
   ((ds, ps) -> int(ds[6])),
   ((ds, ps) -> int(ds[7]))
  ],
  [( log10(4.0 + log(n)), log10(4*n)),
   ( 0.0, 1/7),
   (-2.0, 0.0),
   (0.01, 0.40),
   (2.0, 10.0),
   (2.0, 10.0),
   (20.0, 1000.0)
  ]
)
outfile = "cmsa_es_exp10.csv"
write_csv_header_to_file(pe10, outfile)
run(`/usr/bin/Rscript ../../R/parameter_experiment.R 7 8 16 7 $(outfile) new_runs.json`)
run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe10, outfile; num_repeats = 1)
for i in 1:13
  run(`/usr/bin/Rscript ../../R/parameter_experiment.R 7 1 16 7 $(outfile) new_runs.json sa ei`)
  run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe10, outfile; num_repeats = 1)
end
# Then we maximize the success rate and select the quickest among the top 10.
for i in 1:5
  run(`/usr/bin/Rscript ../../R/parameter_experiment.R 7 1 16 7 $(outfile) new_runs.json sa minquick`)
  run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe10, outfile; num_repeats = 1)
end

# Ok, we have solved Rosenbrock from 8-d to 128-d. Lets address something harder. Griewank?
n = 2
p = as_fixed_dim_problem(BlackBoxOptim.example_problems["Griewank"], n)
p = BlackBoxOptim.shifted(p)
diameter = minimum(diameters(search_space(p)))

pe11 = ParameterExperiment(
  ["lambda", "mu", "sigma", "decompose_covar_prob",
   "max_successes_before_increasing", "max_failures_before_decreasing"
  ],
  [((ds, ps) -> int(10^ds[1])),
   ((ds, ps) -> int(max(1.0, ds[2]*ps[1]))),
   ((ds, ps) -> diameter * 10^ds[3]),
   ((ds, ps) -> ds[4]),
   ((ds, ps) -> int(ds[5])),
   ((ds, ps) -> int(ds[6]))
  ],
  [( log10(4.0 + log(n)), log10(8*n)),
   ( 1/30, 1/6),
   (-2.0, 0.0),
   (0.01, 0.99),
   (2.0, 1000.0),
   (2.0, 1000.0)
  ]
)
outfile = "cmsa_es_exp11.csv"
write_csv_header_to_file(pe11, outfile)
run(`/usr/bin/Rscript ../../R/parameter_experiment.R 6 7 14 6 $(outfile) new_runs.json`)
run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe11, outfile; num_repeats = 1)
for i in 1:13
  run(`/usr/bin/Rscript ../../R/parameter_experiment.R 6 1 13 6 $(outfile) new_runs.json sa ei`)
  run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe11, outfile; num_repeats = 1)
end

# Way too easy with 2-d Griewank though. Lets do 4-D and add all 7 params back in since the default value
# for max rounds without improvement sometimes terminates runs too early if max_failures_before_decreasing
# is also low.
n = 4
p = as_fixed_dim_problem(BlackBoxOptim.example_problems["Griewank"], n)
p = BlackBoxOptim.shifted(p)
diameter = minimum(diameters(search_space(p)))

pe12 = ParameterExperiment(
  ["lambda", "mu", "sigma", "decompose_covar_prob",
   "max_successes_before_increasing", "max_failures_before_decreasing", "max_rounds_without_improvement"
  ],
  [((ds, ps) -> int(10^ds[1])),
   ((ds, ps) -> int(max(1.0, ds[2]*ps[1]))),
   ((ds, ps) -> diameter * 10^ds[3]),
   ((ds, ps) -> ds[4]),
   ((ds, ps) -> int(ds[5])),
   ((ds, ps) -> int(ds[6])),
   ((ds, ps) -> int(10^ds[7]))
  ],
  [( log10(4.0 + log(n)), log10(4*n*n)),
   ( 1/50, 1/2),
   (-2.0, 0.0),
   (0.01, 0.99),
   (-1000.0, 1000.0), # Inactive if less than 1
   (-1000.0, 1000.0), # Inactive if less than 1
   (2.0, 5.0)
  ]
)
outfile = "cmsa_es_exp12.csv"
write_csv_header_to_file(pe12, outfile)
run(`/usr/bin/Rscript ../../R/parameter_experiment.R 7 8 15 7 $(outfile) new_runs.json`)
run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe12, outfile; num_repeats = 1)
for i in 1:5
  run(`/usr/bin/Rscript ../../R/parameter_experiment.R 7 1 15 7 $(outfile) new_runs.json sa alc`)
  run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe12, outfile; num_repeats = 1)
end
for i in 1:10
  run(`/usr/bin/Rscript ../../R/parameter_experiment.R 7 1 16 7 $(outfile) new_runs.json sa min`)
  run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe12, outfile; num_repeats = 1)
end
for i in 1:5
  run(`/usr/bin/Rscript ../../R/parameter_experiment.R 7 1 15 7 $(outfile) new_runs.json sa alc`)
  run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe12, outfile; num_repeats = 1)
end

# The CMSA-ES performs rather badly here. Only one success in many tries, probably just by luck.
# Will need to try with some other CMA versions to see if they can manage with Griewank.

# Lets try a larger Griewank just to be sure it is generally bad for this.
n = 16
p = as_fixed_dim_problem(BlackBoxOptim.example_problems["Griewank"], n)
p = BlackBoxOptim.shifted(p)
diameter = minimum(diameters(search_space(p)))

pe13 = ParameterExperiment(
  ["lambda", "mu", "sigma", "decompose_covar_prob",
   "max_successes_before_increasing", "max_failures_before_decreasing", "max_rounds_without_improvement"
  ],
  [((ds, ps) -> int(10^ds[1])),
   ((ds, ps) -> int(max(1.0, ds[2]*ps[1]))),
   ((ds, ps) -> diameter * 10^ds[3]),
   ((ds, ps) -> ds[4]),
   ((ds, ps) -> int(ds[5])),
   ((ds, ps) -> int(ds[6])),
   ((ds, ps) -> int(10^ds[7]))
  ],
  [( log10(4.0 + log(n)), log10(4*n*n)),
   ( 1/50, 1/2),
   (-3.0, 0.0),
   (0.01, 0.99),
   (-1000.0, 1000.0), # Inactive if less than 1
   (-1000.0, 1000.0), # Inactive if less than 1
   (2.0, 5.0)
  ]
)
outfile = "cmsa_es_exp13.csv"
write_csv_header_to_file(pe13, outfile)
run(`/usr/bin/Rscript ../../R/parameter_experiment.R 7 8 15 7 $(outfile) new_runs.json`)
run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe13, outfile; num_repeats = 10)
for i in 1:12
  run(`/usr/bin/Rscript ../../R/parameter_experiment.R 7 1 15 7 $(outfile) new_runs.json sa alc`)
  run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe13, outfile; num_repeats = 10)
end
for i in 1:10
  run(`/usr/bin/Rscript ../../R/parameter_experiment.R 7 1 19 7 $(outfile) new_runs.json sa alc`)
  run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe13, outfile; num_repeats = 10)
end
for i in 1:10
  run(`/usr/bin/Rscript ../../R/parameter_experiment.R 7 1 -19 7 $(outfile) new_runs.json sa minquick`)
  run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe13, outfile; num_repeats = 10)
end

# Strangely enough it works just fine for 16-D. Very strange. What is the problem with low-dim cases now; have
# I introduced some bias when focusing on the high-dim cases?

# Let's try 8D

n = 8
p = as_fixed_dim_problem(BlackBoxOptim.example_problems["Griewank"], n)
p = BlackBoxOptim.shifted(p)
diameter = minimum(diameters(search_space(p)))

pe = pe14 = ParameterExperiment(
  ["lambda", "mu", "sigma", "decompose_covar_prob",
   "max_successes_before_increasing", "max_failures_before_decreasing", "max_rounds_without_improvement"
  ],
  [((ds, ps) -> int(10^ds[1])),
   ((ds, ps) -> int(max(1.0, ds[2]*ps[1]))),
   ((ds, ps) -> diameter * 10^ds[3]),
   ((ds, ps) -> ds[4]),
   ((ds, ps) -> int(ds[5])),
   ((ds, ps) -> int(ds[6])),
   ((ds, ps) -> int(10^ds[7]))
  ],
  [( log10(4.0 + log(n)), log10(4*n*n)),
   ( 1/50, 1/2),
   (-3.0, 0.0),
   (0.01, 0.99),
   (-1000.0, 1000.0), # Inactive if less than 1
   (-1000.0, 1000.0), # Inactive if less than 1
   (2.0, 5.0)
  ]
)
outfile = "cmsa_es_exp14.csv"
write_csv_header_to_file(pe14, outfile)
run(`/usr/bin/Rscript ../../R/parameter_experiment.R 7 8 15 7 $(outfile) new_runs.json`)
run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe, outfile; num_repeats = 10)
for i in 1:12
  run(`/usr/bin/Rscript ../../R/parameter_experiment.R 7 1 -19 7 $(outfile) new_runs.json not alc`)
  run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe, outfile; num_repeats = 10)
end
for i in 1:5
  run(`/usr/bin/Rscript ../../R/parameter_experiment.R 7 1 -19 7 $(outfile) new_runs.json sa minquick`)
  run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe, outfile; num_repeats = 5)
end

# It worked fine. Strange. lets try 4-d again.
n = 4
p = as_fixed_dim_problem(BlackBoxOptim.example_problems["Griewank"], n)
p = BlackBoxOptim.shifted(p)
diameter = minimum(diameters(search_space(p)))

outfile = "cmsa_es_exp15.csv"
write_csv_header_to_file(pe, outfile)
run(`/usr/bin/Rscript ../../R/parameter_experiment.R 7 8 15 7 $(outfile) new_runs.json`)
run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe, outfile; num_repeats = 10)
for i in 1:12
  run(`/usr/bin/Rscript ../../R/parameter_experiment.R 7 1 -19 7 $(outfile) new_runs.json not alc`)
  run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe, outfile; num_repeats = 10)
end
for i in 1:5
  run(`/usr/bin/Rscript ../../R/parameter_experiment.R 7 1 -19 7 $(outfile) new_runs.json sa minquick`)
  run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe, outfile; num_repeats = 5)
end

# Now it works at least some of the time. So key was to do more than 1 run per setting... Lets try 2-D
n = 2
p = as_fixed_dim_problem(BlackBoxOptim.example_problems["Griewank"], n)
p = BlackBoxOptim.shifted(p)
diameter = minimum(diameters(search_space(p)))

outfile = "cmsa_es_exp16.csv"
write_csv_header_to_file(pe, outfile)
run(`/usr/bin/Rscript ../../R/parameter_experiment.R 7 8 15 7 $(outfile) new_runs.json`)
run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe, outfile; num_repeats = 10)
for i in 1:12
  run(`/usr/bin/Rscript ../../R/parameter_experiment.R 7 1 -19 7 $(outfile) new_runs.json not alc`)
  run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe, outfile; num_repeats = 10)
end
for i in 1:5
  run(`/usr/bin/Rscript ../../R/parameter_experiment.R 7 1 -19 7 $(outfile) new_runs.json sa minquick`)
  run_based_on_design_matrix_in_file_while_saving_results_to_csvfile(cmsa_es, p, pe, outfile; num_repeats = 5)
end

# Looks better. Ok, lets try Sphere 2-D with the new experiment function that
# does it all. Just the simplest test to make sure everything works.

n = 2
p = as_fixed_dim_problem(BlackBoxOptim.example_problems["Sphere"], n)
p = BlackBoxOptim.shifted(p)
diameter = minimum(diameters(search_space(p)))

pe = pe15 = ParameterExperiment(
  ["lambda", "mu", "sigma", "decompose_covar_prob",
   "max_successes_before_increasing", "max_failures_before_decreasing",
   "max_rounds_without_improvement", "tau_c"
  ],
  [((ds, ps) -> int(10^ds[1])),
   ((ds, ps) -> int(max(1.0, ds[2]*ps[1]))),
   ((ds, ps) -> diameter * 10^ds[3]),
   ((ds, ps) -> ds[4]),
   ((ds, ps) -> int(ds[5])),
   ((ds, ps) -> int(ds[6])),
   ((ds, ps) -> int(10^ds[7])),
   ((ds, ps) -> 1 + n * (n+1) / (ds[8]*ps[2]))
  ],
  [( log10(4.0 + log(n)), log10(4*n*n)),
   ( 1/50, 1/2),
   (-3.0, 0.0),
   (0.01, 0.99),
   (-1000.0, 1000.0), # Inactive if less than 1
   (-1000.0, 1000.0), # Inactive if less than 1
   (1.0, 4.0),
   (0.01, 100.0)
  ]
)

# Do when with fewer repeats just to test things...
explore_parameters(pe15, cmsa_es, p; experiment_prefix = "cmsa_es", num_repeats = 10)


text:
module QuantInstr

using ..Utils

export @quip, QInstr

"""
Quantum Instruction each gate represents an operation on the state of the wave function
"""
struct QInstr
    op::Symbol             # Operation code
    func::Function         # Store the subroutine when op == :callfun

    param::Vector{Float64} # Parameters for op or func

    # Specify qBits that are acted on
    # In measurement mode, specify [target qbit, target cbit]
    target::Vector{Int}

    # specify control bits
    # negative value indicates control-on-zero
    control::Vector{Int}
    cbit_ctrl::Bool        # True means the control bits are classical
end

# Show interface for gate
function Base.show(io::IO, g::QInstr)
    op = g.op
    param = g.param

    # Function call mode
    if op == :funcall
        funcall = Expr(:call, g.func, param...)
        show(io, "$funcall")

        # Measurement mode
    elseif op == :measure
        qbit = g.target[1]
        cbit = Expr(:ref, :C, g.target[2])
        show(io, "$qbit => $cbit")
        # Standard gate mode
    else
        op_param = isempty(param) ? op : Expr(:call, op, param...)

        target = length(g.target) == 1 ? g.target[1] : tuple(g.target...)

        ctrl_expr = g.cbit_ctrl ? [Expr(:ref, :C, i) for i in g.control] : g.control
        control = length(ctrl_expr) == 1 ? ctrl_expr[1] : tuple(ctrl_expr...)

        if isempty(ctrl_expr)
            show(io, "$op_param >> $target")
        else
            show(io, "$op_param >> $target | $control")
        end
    end
end

#######################################################
# Functions that helps streamline the parsing procedure
force_params(s::Symbol) = Expr(:call, s)
force_params(e::Expr) = e

force_tuple(n::Number) = Expr(:tuple, n)
force_tuple(s::Symbol) = Expr(:tuple, s)
function force_tuple(e::Expr)
    if e.head == :tuple
        e
    else
        Expr(:tuple, e)
    end
end

# Flatten instruction collections
flatten(i::QInstr) = [i]
function flatten(a::AbstractArray)
    flattened = [flatten(i) for i in a]
    vcat(flattened...)
end

dummyfun() = 1 # dummy function

#########################################
# Parsing classical bit expressions: C[i]
function parse_cbit(expr::Expr)
    @assert expr.head == :ref "Not a classical bit: $expr"
    @assert expr.args[1] == :C "Bits can only take the form C[i]"
    return expr.args[2]
end

parse_cbit(other) = throw("Not a classical bit: $other")

###################################
# Parsing "not" expressions: !Expr
function parse_not(expr::Expr)
    if expr.head == :call && expr.args[1] == :!
        (-1, expr.args[2])
    else
        (1, expr)
    end
end

parse_not(other) = (1, other)

"""
Parses a QInsr expression
"""
function parse_entry(entry::Expr)
    ##############################################
    # List expresion:
    # 	[sub expression 1, sub expression 2, ...]
    if entry.head == :vcat || entry.head == :vect
        parsed = [parse_entry(e) for e in entry.args]
        return Expr(:vcat, parsed...)

    ##############################################
    # List comprehension expression:
    # 	[sub_expr for_expr if_expr]
    elseif entry.head == :comprehension
        generator = entry.args[1]
        generator.args[1] = parse_entry(generator.args[1])
        generator.args[2] = esc(generator.args[2])
        return Expr(:comprehension, generator)

    ###############################
    # QInstr expression
    # 	+ Measure mode
    #	+ Standard gate mode
    #	+ Function call mode
    elseif entry.head == :call
        control = []
        classical = []
        cbit_ctrl = false
        funcall = dummyfun # dummy function

        ####################################
        # Measure mode: qBit => cBit
        if entry.args[1] == :(=>)
            op = Meta.quot(:measure)
            qbit = entry.args[2]
            cbit = parse_cbit(entry.args[3])
            target = Expr(:vect, qbit, cbit)

            return :(QInstr($op, $funcall, [], $target, $control, $cbit_ctrl))
        end

        ###################################################
        # Standard gate mode: OP(param) >> target | control
        if entry.args[1] == :| # Parsing control
            control_expr = force_tuple(entry.args[3]).args

            # Parsing NOT'ed expressions
            control_expr = parse_not.(control_expr)

            # Check for classical control mode
            if typeof(control_expr[1][2]) == Expr
                cbit_ctrl = control_expr[1][2].head == :ref
            end

            # Process control bit expressions depends on cbit_mode
            if cbit_ctrl
                # Parse cBit values
                control_expr = [(mult, parse_cbit(expr))
                                for (mult, expr) in control_expr]

            # qbit mode
            else
                # sanity check
                for expr in control_expr
                    if typeof(expr) == Expr
                        @assert expr.head != :ref "not a qBit $expr"
                    end
                end
            end
            # Applying NOT'ed expressions
            control_expr = [Expr(:call, :*, mult, expr)
                            for (mult, expr) in control_expr]

            control = esc(Expr(:vect, control_expr...))
            entry = entry.args[2]
        end

        @assert entry.head == :call "Invalid quip entry $entry"
        if entry.args[1] == :>> # Parsing Operation
            # Parse target
            target = esc(Expr(:vect, force_tuple(entry.args[3]).args...))
            # Parse op and param
            op_and_param = force_params(entry.args[2]).args
            op = Meta.quot(op_and_param[1])
            param = esc(Expr(:vect, op_and_param[2:end]...))

            return :(QInstr($op, $funcall, $param, $target, $control, $cbit_ctrl))
        end

        ##################################
        # Function call mode: func(param)
        op_and_param = entry.args
        op = Meta.quot(:funcall)
        param = esc(Expr(:vect, op_and_param[2:end]...))

        func = esc(op_and_param[1])

        return :(QInstr($op, $func, $param, [], $control, $cbit_ctrl))

    # Branch expression a ? b : c
    elseif entry.head == :if
        a = entry.args[1]
        b = entry.args[2]
        c = entry.args[3]
        return Expr(:if, esc(a), parse_entry(b), parse_entry(c))

    # Dot expression a.b
	elseif entry.head == :(.)
		return entry
    end

    throw("can't parse $entry")
end

function parse_entry(entry::Symbol)
    esc(entry)
end

"""
Usage:
@quip <quip expression>
"""
macro quip(expr)
    if expr.head == :(=)
        lhs = expr.args[1]
        rhs = expr.args[2]
    else
        rhs = expr
    end

    if rhs.head == :block
        rhs = rhs.args[2]
    end

    rhs = parse_entry(rhs)

    rhs = Expr(:call, :flatten, rhs)
    if expr.head == :(=)
        :($(esc(lhs)) = $rhs)
    else
        :($rhs)
    end
end

end


text:
module BattleEnums

@enum BattleFormat begin
    SINGLE
    DOUBLE
    # TODO: Include different rules?
end

@enum BattleResult begin
    WIN
    LOSE
    TIE
end

end

@missable mutable struct Event
    id::Int64
    turn::Int64
    # types are defined in `battle.yaml`
    type::String
    args::Vector{String}
end

@missable mutable struct Battle
    format::BattleEnums.BattleFormat
    player::Player = Player()
    opponent::Player = Player()
    opponent_team::Vector{PokemonID}
    events::Vector{Event} = Event[]
end

# Parsed Data from events
@missable mutable struct ParsedBattle
    result::BattleEnums.BattleResult
    team_a::Team
    team_b::Team
end

update_team!(::Missing, _...) = missing
function update_team!(battle::ParsedBattle, is_team_a::Bool, args...)
    if is_team_a
        if ismissing(battle.team_a)
            battle.team_a = Team()
        end
        update_team!(battle.team_a, args...)
    else
        if ismissing(battle.team_b)
            battle.team_b = Team()
        end
        update_team!(battle.team_b, args...)
    end
    battle
end


text:
# load solver
using HALeqO

# load tools
using SolverBenchmark

# load problems
using CUTEst
probnames = CUTEst.select(
    min_var = 1,
    min_con = 1,
    max_var = 2,
    max_con = 2,
    only_free_var = true,
    only_equ_con = true,
)

# setup testing
problems = (CUTEstModel(probname) for probname in probnames)
solver = prob -> haleqo(prob)

# run solver!
stats = solve_problems(solver, problems)

# get statistics
@info "HALeqO statuses" count_unique(stats.status)
num_solved_problems = sum(stats.status .== :first_order)


text:
using ExtendedIntegers
using Base.Test

import ExtendedIntegers: _mul, _mul2, _divrem, _divrem2, _estimateq, fullshift
# random tests
const F = FlexibleUInt{UInt8}
for k in 1:100000
    a = rand(UInt64)
    # convert
    @test convert(UInt64, convert(F, a)) == a
    # left shift
    for s = 0:64
        @test convert(F, a >> s) == convert(F, a) >> s
    end
    # right shift
    a = UInt64(rand(UInt32))
    for s = 0:32
        @test convert(F, a << s) == convert(F, a) << s
    end
    # bitwise and an or
    a = rand(UInt64)
    b = rand(UInt32)
    @test convert(F, a & b) == convert(F,a) & convert(F,b)
    @test convert(F, a | b) == convert(F,a) | convert(F,b)
    # add
    a = rand(UInt64)>>1
    b = rand(UInt64)>>1
    @test convert(F, a + b) == convert(F,a) + convert(F,b)
    # subtract
    a = rand(UInt64)
    b = rand(zero(a):a)
    @test convert(F, a - b) == convert(F,a) - convert(F,b)
    # mul
    a = rand(UInt32)
    b = rand(UInt32)
    @test convert(F, widen(a)*widen(b)) == convert(F,a) * convert(F,b)
    # div
for k in 1:10000
    a = rand(UInt64)
    b = rand(UInt32)
    @test map(F, divrem(a,b)) == divrem(convert(F,a), convert(F,b))
end

#
# U = UInt8
# for a in zero(U):typemax(U), b in zero(U):typemax(U)
#     @test _mul(a,b) == _mul2(a,b)
# end
# for a0 in zero(U):typemax(U), d in one(U):typemax(U)
#     for a1 in zero(U):(d-one(U))
#         @test _divrem(a0,a1,d) == _divrem2(a0,a1,d)
#     end
# end

U = UInt8
for k in 1:1000000
    v = rand((typemax(U)>>1+one(U)):typemax(U))
    u′′, u′, v′ = rand(U,4)
    if  v′ > u′
        u = rand(zero(U):v)
    else
        u = rand(zero(U):(v-one(v)))
    end
    num = UInt64(u)<<(2*fullshift(U)) + UInt64(u′)<<fullshift(U) + UInt64(u′′)
    den = UInt64(v)<<fullshift(U) + UInt64(v′)
    @test div(num,den) == _estimateq(u′′,u′,u,v′,v)
end

for k in 1:10000
    a = rand(UInt64)
    b = rand(UInt64)
    @test convert(F, a & b) == convert(F, a) & convert(F, b)
    @test convert(F, a | b) == convert(F, a) | convert(F, b)
    a >>= 1
    b >>= 1
    @test convert(F, a + b) == convert(F, a) + convert(F, b)
    a = rand(UInt64)
    b = rand(zero(a):a)
    @test convert(F, a - b) == convert(F, a) - convert(F, b)
    a = UInt64(rand(UInt32))
    b = UInt64(rand(UInt32))
    @test convert(F, a * b) == convert(F, a) * convert(F, b)
end

# write your own tests here
# const T = UInt16
# for k in UInt16(0):typemax(T)
#     @test k == convert(T, convert(FlexibleUInt{UInt8},k))
#     @test k == convert(T, convert(FlexibleUInt{UInt16},k))
#     @test k == convert(T, convert(FlexibleUInt{UInt32},k))
#     @test k == convert(T, convert(FlexibleUInt{UInt64},k))
#
#     @test k == convert(UInt32, convert(FlexibleUInt{UInt8},k))
#     @test k == convert(UInt64, convert(FlexibleUInt{UInt8},k))
#
#
# end


text:
using OMEinsum, StatsBase
using DelimitedFiles
using OMEinsum: DynamicEinCode, StaticEinCode

function random_contract(D, dynamic, uniqueindex, nodangling)
    Ds = [rand(1:D) for _=1:3]
    T = Ds[1] + Ds[2]
    ixs = Tuple.((sample(1:T, Ds[1]; replace=!uniqueindex), sample(1:T, Ds[2]; replace=!uniqueindex)))
    allinds = ixs[1] ∪ ixs[2]
    iy = sample(allinds, min(Ds[3], length(allinds)); replace=!uniqueindex)
    if nodangling
        iy = Tuple(iy ∪ setdiff(allinds, iy))  # no dangling legs
    else
        iy = Tuple(iy)
    end
    xs = (randn(fill(2, Ds[1])...), randn(fill(2, Ds[2])...))
    if dynamic
        DynamicEinCode(ixs, iy)(xs...)
    else
        StaticEinCode{ixs,iy}()(xs...)
    end
end

function benchmark_compiletime(; D, nrepeat, dynamic, uniqueindex, nodangling, write=false)
    times = zeros(nrepeat)
    for i=1:nrepeat
        @show i
        times[i] = @elapsed random_contract(D, dynamic, uniqueindex, nodangling)
    end
    if write
        output_file=joinpath(@__DIR__, "compiletime_$(D)_$(dynamic)_$(uniqueindex).dat")
        writedlm(output_file, times)
    end
    return times
end

times = benchmark_compiletime(D=8, nrepeat=1000, dynamic=true, uniqueindex=true, nodangling=true, write=true)

#using Profile
#@profile for i=1:10 random_contract(8, true, true, true) end


text:
#=
This file is auto-generated. Do not edit.
=#
"""
    mutable struct EPANETPumpParams <: TechnicalParams
        epnt_type::Union{Nothing, String}
        epnt_power::Union{Nothing, Float64}
        epnt_head::Union{Nothing, Curve}
        epnt_efficiency::Union{Nothing, Float64, Curve}
        internal::InfrastructureSystemsInternal
    end

Pump specifications from inp-file

# Arguments
- `epnt_type::Union{Nothing, String}`: epanet categorizes pump specs as HEAD or POWER
- `epnt_power::Union{Nothing, Float64}`: specified constant power if type POWER
- `epnt_head::Union{Nothing, Curve}`: provided head curve if type HEAD
- `epnt_efficiency::Union{Nothing, Float64, Curve}`: provided efficiency curve (or single value) if type HEAD
- `internal::InfrastructureSystemsInternal`: internal reference, do not modify
"""
mutable struct EPANETPumpParams <: TechnicalParams
    "epanet categorizes pump specs as HEAD or POWER"
    epnt_type::Union{Nothing, String}
    "specified constant power if type POWER"
    epnt_power::Union{Nothing, Float64}
    "provided head curve if type HEAD"
    epnt_head::Union{Nothing, Curve}
    "provided efficiency curve (or single value) if type HEAD"
    epnt_efficiency::Union{Nothing, Float64, Curve}
    "internal reference, do not modify"
    internal::InfrastructureSystemsInternal
end

function EPANETPumpParams(epnt_type, epnt_power, epnt_head, epnt_efficiency, )
    EPANETPumpParams(epnt_type, epnt_power, epnt_head, epnt_efficiency, InfrastructureSystemsInternal(), )
end

function EPANETPumpParams(; epnt_type, epnt_power, epnt_head, epnt_efficiency, )
    EPANETPumpParams(epnt_type, epnt_power, epnt_head, epnt_efficiency, )
end

# Constructor for demo purposes; non-functional.
function EPANETPumpParams(::Nothing)
    EPANETPumpParams(;
        epnt_type=nothing,
        epnt_power=nothing,
        epnt_head=nothing,
        epnt_efficiency=nothing,
    )
end

"""Get EPANETPumpParams epnt_type."""
get_epnt_type(value::EPANETPumpParams) = value.epnt_type
"""Get EPANETPumpParams epnt_power."""
get_epnt_power(value::EPANETPumpParams) = value.epnt_power
"""Get EPANETPumpParams epnt_head."""
get_epnt_head(value::EPANETPumpParams) = value.epnt_head
"""Get EPANETPumpParams epnt_efficiency."""
get_epnt_efficiency(value::EPANETPumpParams) = value.epnt_efficiency
"""Get EPANETPumpParams internal."""
get_internal(value::EPANETPumpParams) = value.internal


text:
@testset "ellipse" begin
    p = Point([-73.9975, 40.730833])

    @test ellipse(center=p, xAxis=5., yAxis=1., pivot=nothing).coordinates ≈ [
					[
						[
							-73.938161,
							40.730833
						],
						[
							-73.947745,
							40.735733
						],
						[
							-73.961537,
							40.737986
						],
						[
							-73.970979,
							40.738878
						],
						[
							-73.97711,
							40.739279
						],
						[
							-73.981313,
							40.739485
						],
						[
							-73.984374,
							40.739603
						],
						[
							-73.986724,
							40.739677
						],
						[
							-73.988608,
							40.739725
						],
						[
							-73.990176,
							40.739757
						],
						[
							-73.991522,
							40.73978
						],
						[
							-73.992709,
							40.739797
						],
						[
							-73.993782,
							40.739809
						],
						[
							-73.994775,
							40.739817
						],
						[
							-73.995712,
							40.739822
						],
						[
							-73.996614,
							40.739825
						],
						[
							-73.9975,
							40.739826
						],
						[
							-73.998386,
							40.739825
						],
						[
							-73.999288,
							40.739822
						],
						[
							-74.000225,
							40.739817
						],
						[
							-74.001218,
							40.739809
						],
						[
							-74.002291,
							40.739797
						],
						[
							-74.003478,
							40.73978
						],
						[
							-74.004824,
							40.739757
						],
						[
							-74.006392,
							40.739725
						],
						[
							-74.008276,
							40.739677
						],
						[
							-74.010626,
							40.739603
						],
						[
							-74.013687,
							40.739485
						],
						[
							-74.01789,
							40.739279
						],
						[
							-74.024021,
							40.738878
						],
						[
							-74.033463,
							40.737986
						],
						[
							-74.047255,
							40.735733
						],
						[
							-74.056839,
							40.730833
						],
						[
							-74.047255,
							40.725933
						],
						[
							-74.033463,
							40.72368
						],
						[
							-74.024021,
							40.722788
						],
						[
							-74.01789,
							40.722387
						],
						[
							-74.013687,
							40.722181
						],
						[
							-74.010626,
							40.722063
						],
						[
							-74.008276,
							40.721989
						],
						[
							-74.006392,
							40.721941
						],
						[
							-74.004824,
							40.721909
						],
						[
							-74.003478,
							40.721886
						],
						[
							-74.002291,
							40.721869
						],
						[
							-74.001218,
							40.721857
						],
						[
							-74.000225,
							40.721849
						],
						[
							-73.999288,
							40.721844
						],
						[
							-73.998386,
							40.721841
						],
						[
							-73.9975,
							40.72184
						],
						[
							-73.996614,
							40.721841
						],
						[
							-73.995712,
							40.721844
						],
						[
							-73.994775,
							40.721849
						],
						[
							-73.993782,
							40.721857
						],
						[
							-73.992709,
							40.721869
						],
						[
							-73.991522,
							40.721886
						],
						[
							-73.990176,
							40.721909
						],
						[
							-73.988608,
							40.721941
						],
						[
							-73.986724,
							40.721989
						],
						[
							-73.984374,
							40.722063
						],
						[
							-73.981313,
							40.722181
						],
						[
							-73.97711,
							40.722387
						],
						[
							-73.970979,
							40.722788
						],
						[
							-73.961537,
							40.72368
						],
						[
							-73.947745,
							40.725933
						],
						[
							-73.938161,
							40.730833
						]
					]] atol=0.1
end


text:
# SPDX-License-Identifier: MIT

abstract type BMObject end

const BMObjectList{N,T<:BMObject} = NTuple{N,T}

function iscomposite(obj::T) where T<:BMObject
    for name in fieldnames(typeof(obj))
        prop = getproperty(obj, name)
        if typeof(prop) <: BMObject
            return true
        elseif typeof(prop) <: BMObjectList
            return true
        end
    end
    return false
end

function Base.show(io::IO, mime::MIME"text/plain", obj::BMObject)
    indent = get(io, :indent, 0)
    prefix = get(io, :prefix, "")
    parents = get(io, :parents, [])

    if ! iscomposite(obj)
        println(io, " "^indent, prefix, typeof(obj))
        return
    end

    println(io, " "^indent, prefix, typeof(obj), " (")
    for name in fieldnames(typeof(obj))
        prop = getproperty(obj, name)
        if typeof(prop) <: BMObject
            io2 = IOContext(io, :indent => indent+2, :prefix => "($(name)): ")
            show(io2, mime, prop)
        elseif typeof(prop) <: BMObjectList
            println(io, " "^(indent+2), "($name): [")
            for (i, param) in enumerate(prop)
                io2 = IOContext(io, :indent => indent+4, :prefix => "($(i)): ")
                show(io2, mime, param)
            end
            println(io, " "^(indent+2), "]")
        end
    end
    println(io, " "^indent, ")")
end

max_stars_repo_name: BUTSpeechFIT/PPCA

max_issues_repo_name: BUTSpeechFIT/PPCA

max_forks_repo_name: BUTSpeechFIT/PPCA


text:
# Source CODATA2018 https://physics.nist.gov/cuu/Constants/
module Constants

using ..Units: m, s, c, u, kg, eV, keV, MeV, lm, W, K, m, atm, Torr, Hz, Ω

# import constants defined in Unitful
using Unitful
import Unitful: c0, k, μ0, q, ϵ0, ε0, Z0, me, mp, mn, G, gn, h, ħ, μB, Na, R, σ, R∞, μB

# Masses and Charges
const AtomicMassUnit = uconvert(kg, 1u)
const mu = AtomicMassUnit
export AtomicMassUnit

const ElectronMass = me
const ElectronAtomicMass = 5.48579909065e-4u
const Ae = ElectronAtomicMass
const ElectronRestMass = 0.51099895000MeV/c^2
const me0 = ElectronRestMass
const ElectronChargeNumber = -1
const Ze = ElectronChargeNumber
export ElectronMass, ElectronAtomicMass, ElectronRestMass, ElectronChargeNumber

const ProtonMass = mp
const ProtonAtomicMass = 1.007276466621u
const Ap = ProtonAtomicMass
const ProtonRestMass = 938.27208816MeV/c^2
const mp0 = ProtonRestMass
const ProtonChargeNumber = 1
const Zp = ProtonChargeNumber
export ProtonMass, ProtonAtomicMass, ProtonRestMass, ProtonChargeNumber

const NeutronMass = mn
const NeutronAtomicMass = 1.00866491595u
const An = NeutronAtomicMass
const NeutronRestMass = 939.56542052MeV/c^2
const mn0 = NeutronRestMass
const NeutronChargeNumber = 0
const Zn = NeutronChargeNumber
export NeutronMass, NeutronAtomicMass, NeutronRestMass, NeutronChargeNumber

const DeuteronMass = 3.3435837724e-27kg
const md = DeuteronMass
const DeuteronAtomicMass = 2.013553212745u
const Ad = DeuteronAtomicMass
const DeuteronRestMass = 1875.61294257MeV/c^2
const md0 = DeuteronRestMass
const DeuteronChargeNumber = 1
const Zd = DeuteronChargeNumber
export DeuteronMass, DeuteronAtomicMass, DeuteronRestMass, DeuteronChargeNumber

const TritonMass = 5.0073567446e-27kg
const mt = TritonMass
const TritonAtomicMass = 3.01550071621u
const At = TritonAtomicMass
const TritonRestMass = 2808.92113298MeV/c^2
const mt0 = TritonRestMass
const TritonChargeNumber = 1
const Zt = TritonChargeNumber
export TritonMass, TritonAtomicMass, TritonRestMass, TritonChargeNumber

const HelionMass = 5.0064127796e-27kg
const mh = HelionMass
const HelionAtomicMass = 3.014932247175u
const Ah = HelionAtomicMass
const HelionRestMass = 2808.39160743MeV/c^2
const mh0 = HelionRestMass
const HelionChargeNumber = 2
const Zh = HelionChargeNumber
export HelionMass, HelionAtomicMass, HelionRestMass, HelionChargeNumber

const AlphaMass = 6.6446573357e-27kg
const mα = AlphaMass
const ma = mα
const AlphaAtomicMass = 4.001506179127u
const Aα = AlphaAtomicMass
const Aa = Aα
const AlphaRestMass = 3727.3794066MeV/c^2
const mα0 = AlphaRestMass
const ma0 = mα0
const AlphaChargeNumber = 2
const Zα = AlphaChargeNumber
const Za = Zα
export AlphaMass, AlphaAtomicMass, AlphaRestMass, AlphaChargeNumber

# Impurity Atomic Masses
const LithiumAtomicMass = 6.941u
const Lithium6AtomicMass = 6.938u
const Lithium7AtomicMass = 6.997u
const LithiumMass = uconvert(kg, LithiumAtomicMass)
const Lithium6Mass = uconvert(kg, Lithium6AtomicMass)
const Lithium7Mass = uconvert(kg, Lithium7AtomicMass)
const LithiumChargeNumber = 1
export LithiumAtomicMass, Lithium6AtomicMass, Lithium7AtomicMass
export LithiumMass, Lithium6Mass, Lithium7Mass
export LithiumChargeNumber

const BerylliumAtomicMass = 9.0121831u
const BerylliumMass = uconvert(kg, BerylliumAtomicMass)
const BerylliumChargeNumber = 2
export BerylliumAtomicMass, BerylliumMass, BerylliumChargeNumber

const BoronAtomicMass = 10.811u
const Boron10AtomicMass = 10.806u
const Boron11AtomicMass = 10.821u
const BoronMass = uconvert(kg, BoronAtomicMass)
const Boron10Mass = uconvert(kg, Boron10AtomicMass)
const Boron11Mass = uconvert(kg, Boron11AtomicMass)
const BoronChargeNumber = 5
export BoronAtomicMass, Boron10AtomicMass, Boron11AtomicMass
export BoronMass, Boron10Mass, Boron11Mass
export BoronChargeNumber

const CarbonAtomicMass = 12.011u
const Carbon12AtomicMass = 12.0096u
const Carbon13AtomicMass = 12.0116u
const CarbonMass = uconvert(kg, CarbonAtomicMass)
const Carbon12Mass = uconvert(kg, Carbon12AtomicMass)
const Carbon13Mass = uconvert(kg, Carbon13AtomicMass)
const CarbonChargeNumber = 6
export CarbonAtomicMass, Carbon12AtomicMass, Carbon13AtomicMass
export CarbonMass, Carbon12Mass, Carbon13Mass
export CarbonChargeNumber

const NitrogenAtomicMass = 14.007u
const Nitrogen14AtomicMass = 14.00643u
const Nitrogen15AtomicMass = 14.00728u
const NitrogenMass = uconvert(kg, NitrogenAtomicMass)
const Nitrogen14Mass = uconvert(kg, Nitrogen14AtomicMass)
const Nitrogen15Mass = uconvert(kg, Nitrogen15AtomicMass)
const NitrogenChargeNumber = 7
export NitrogenAtomicMass, Nitrogen14AtomicMass, Nitrogen15AtomicMass
export NitrogenMass, Nitrogen14Mass, Nitrogen15Mass
export NitrogenChargeNumber

const OxygenAtomicMass = 15.999u
const OxygenMass = uconvert(kg, OxygenAtomicMass)
const OxygenChargeNumber = 8
export OxygenAtomicMass, OxygenMass, OxygenChargeNumber

# Physical Constants
const ProtonElectronMassRatio = 1836.15267343
const ElectronProtonMassRatio = 5.44617021487e-4
export ProtonElectronMassRatio, ElectronProtonMassRatio

const GravitationalConstant = G
const GravitationalAcceleration = gn
export GravitationalConstant, GravitationalAcceleration

const PlanckConstant = h
const ReducedPlanckConstant = ħ
export PlanckConstant, ReducedPlanckConstant

const ElementaryCharge = q
const ElectronChargeMassRatio = q/me
export ElementaryCharge, ElectronChargeMassRatio

const BoltzmannConstant = k
const StephanBoltzmannConstant = σ
export BoltzmannConstant, StephanBoltzmannConstant

const SpeedOfLightInVacuum = c0
const PermittivityOfFreeSpace = ε0
const PermeabilityOfFreeSpace = μ0
const ImpedanceOfVacuum = Z0
export SpeedOfLightInVacuum, PermittivityOfFreeSpace, PermeabilityOfFreeSpace, ImpedanceOfVacuum

const RydbergConstant = R∞
const Ry = 13.605693122994eV
const RydbergEnergy = Ry
const RydbergFrequency = c0*R∞
const cR∞ = RydbergFrequency
export RydbergConstant, RydbergEnergy, RydbergFrequency

const BohrRadius = ϵ0*h^2/(pi*me*q^2)
const a0 = BohrRadius
const AtomicCrossSection = pi*a0^2
const r_e = (q^2)/(4pi*ϵ0*me*c0^2)
const ClassicalElectronRadius = r_e
const ThomsonCrossSection = (8pi/3)*r_e^2
const σTh = ThomsonCrossSection
const BohrMagneton = μB
export BohrRadius, AtomicCrossSection, ClassicalElectronRadius, ThomsonCrossSection, BohrMagneton

const ComptonWavelength = h/(me*c0)
const λC  = ComptonWavelength
const ReducedComptonWavelength = ħ/(me*c0)
const ƛC = ReducedComptonWavelength
export ComptonWavelength, ReducedComptonWavelength

const FineStructureConstant = 7.2973525693e-3
const α = FineStructureConstant
const InverseFineStructureConstant = 137.035999084
const inv_α = InverseFineStructureConstant
export FineStructureConstant, InverseFineStructureConstant

const FirstRadiationConstant = 2π*h*c0
const c1 = FirstRadiationConstant
const SecondRadiationConstant = h*c0/k
const c2 = SecondRadiationConstant
export FirstRadiationConstant, SecondRadiationConstant

const λ0 = h*c0/q
const ElectronVoltWavelength = λ0
const ν0 = q/h
const ElectronVoltFrequency = ν0
const k0 = q/(h*c0)
const ElectronVoltWaveNumber = k0
const ElectronVoltTemperature = k/q
const TemperatureElectronVolt = q/k
export ElectronVoltWavelength, ElectronVoltFrequency, ElectronVoltWaveNumber, ElectronVoltTemperature, TemperatureElectronVolt

const AvogadroNumber = Na
const FaradayConstant = Na*q
const F = FaradayConstant
const MolarGasConstant = R
const LoschmidtsNumber = 2.6868e25m^-3
const n0 = LoschmidtsNumber
const StandardTemperature = 273.15K
const T0 = StandardTemperature
const StandardPressure = 1atm
const p0 = 1atm
const mmHg = 1Torr
const StandardVolume = R*T0/p0
const V0 = StandardVolume
const M_air = 2.8971e-2kg
const MolarWeightOfAir = M_air
export AvogadroNumber, FaradayConstant, MolarGasConstant, LoschmidtsNumber
export StandardTemperature, StandardPressure, StandardVolume, MolarWeightOfAir

# Miscellaneous Constants
const Cs133HyperfineTransitionFrequency = 9192631770Hz
const ΔνCs133 = Cs133HyperfineTransitionFrequency
const LuminousEfficacy = 683lm/W
const Kcd = LuminousEfficacy
const JosephsonConstant = 2q/h
const KJ = JosephsonConstant
const VonKlitzingConstant = uconvert(Ω, h/q^2)
const RK = VonKlitzingConstant
export Cs133HyperfineTransitionFrequency, LuminousEfficacy, JosephsonConstant, VonKlitzingConstant

end


text:
# Autogenerated wrapper script for FastJet_Julia_Wrapper_jll for x86_64-linux-musl-cxx03-julia_version+1.8.0
export libfastjetwrap

using libcxxwrap_julia_jll
using FastJet_jll
JLLWrappers.@generate_wrapper_header("FastJet_Julia_Wrapper")
JLLWrappers.@declare_library_product(libfastjetwrap, "libfastjetwrap.so")
function __init__()
    JLLWrappers.@generate_init_header(libcxxwrap_julia_jll, FastJet_jll)
    JLLWrappers.@init_library_product(
        libfastjetwrap,
        "lib/libfastjetwrap.so",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@generate_init_footer()
end  # __init__()


text:
module UNet

using Flux, Images
using Flux: @treelike

# model
export unet

# utilities
export img2array, array2img, unet_tiling

include("model.jl")
include("utils.jl")

end # module


text:
import Base: *, ==, copy

"""
    Scalar

A struct for recording the scalars when we rewrite ZX-diagrams.
"""
mutable struct Scalar{P}
    power_of_sqrt_2::Int
    phase::P
    function Scalar{P}(n = 0, p = zero(P)) where {P}
        return new{P}(Int(n), P(p))
    end
end

function Scalar(n = 0, p = Phase(0//1))
    return Scalar{Phase}(n, Phase(p))
end

function add_power!(s::Scalar, n)
    s.power_of_sqrt_2 += Int(n)
    return s
end

function add_phase!(s::Scalar{P}, p) where {P}
    s.phase += P(p)
    return s
end

*(s1::Scalar, s2::Scalar) = Scalar(s1.power_of_sqrt_2 + s2.power_of_sqrt_2, s1.phase + s2.phase)
==(s1::Scalar, s2::Scalar) = (s1.power_of_sqrt_2 == s2.power_of_sqrt_2 && s1.phase == s2.phase)
copy(s::Scalar{P}) where {P} = Scalar{P}(s.power_of_sqrt_2, s.phase)