packages feed

limp-cbc-0.2.8.6: src/Numeric/Limp/Solvers/Cbc/Internal/Foreign.chs

{-# OPTIONS_GHC -fno-warn-unused-binds -fno-warn-unused-do-bind -fno-warn-unused-matches #-}
module Numeric.Limp.Solvers.Cbc.Internal.Foreign where

import Foreign
import Foreign.C

import Control.Applicative

import qualified Data.Vector.Storable as V
import Data.Vector.Storable (Vector)

import Unsafe.Coerce

#include "Cbc.h"


newtype CbcModel = CbcModel (ForeignPtr CbcModel)
{#pointer *CbcModel as CbcModelPtr -> CbcModel #}


foreign import ccall "&freeModel"
   cbcDeleteModel_funptr :: FunPtr (Ptr CbcModel -> IO ())

mkCbcModel :: CbcModelPtr -> IO CbcModel
mkCbcModel p
    = CbcModel <$> newForeignPtr cbcDeleteModel_funptr p

withCbcModel :: CbcModel -> (CbcModelPtr -> IO b) -> IO b
withCbcModel (CbcModel ptr) f
    = do    withForeignPtr ptr f

{#fun newModel as ^
    { } -> `CbcModel' mkCbcModel* #}

withVecI    :: Vector Int -> (Ptr CInt -> IO b) -> IO b
withVecI v f
 = V.unsafeWith (V.map fromIntegral v) f

withVecD    :: Vector Double -> (Ptr CDouble -> IO b) -> IO b
withVecD v f
 = V.unsafeWith v (f . castPtr)


{#fun loadProblem as ^
    { withCbcModel* `CbcModel'

    ,               `Int'               -- # rows
    ,               `Int'               -- # columns

    , withVecI*     `Vector Int'        -- starts
    , withVecI*     `Vector Int'        -- indices
    , withVecD*     `Vector Double'     -- values

    , withVecD*     `Vector Double'     -- col lower bounds
    , withVecD*     `Vector Double'     -- col upper bounds

    , withVecD*     `Vector Double'     -- objective coefficients
    , withVecD*     `Vector Double'     -- row lower bounds
    , withVecD*     `Vector Double'     -- row upper bounds
    }
    -> `()' #}


{#fun setInteger as ^
    { withCbcModel* `CbcModel'
    ,               `Int' }
    -> `()' #}


{#fun branchAndBound as ^
    { withCbcModel* `CbcModel' }
    -> `()' #}


getSolution :: CbcModel -> IO (Vector Double)
getSolution m
 = do   ncols <- fromIntegral <$> withCbcModel m {#call getNumCols#}
        vd    <- unsafeCoerce <$> withCbcModel m {#call getBestSolution#}

        V.generateM ncols (peekElemOff vd)


{#fun setObjSense as ^
    { withCbcModel* `CbcModel'
    ,               `Double' }
    -> `()' #}


{#fun setLogLevel as ^
    { withCbcModel* `CbcModel'
    ,               `Int' }
    -> `()' #}


{#fun isProvenInfeasible as ^
    { withCbcModel* `CbcModel' }
    -> `Bool' #}


{#fun pure getCoinDblMax as ^
    { } -> `Double' #}