packages feed

qhull-0.1.0.1: src/HalfSpaces/HalfSpaces.hs

module HalfSpaces.HalfSpaces
  where
import           Control.Monad          (unless, when, (<$!>), (=<<))
import           Foreign.C.Types
import           Foreign.Marshal.Alloc  (free, mallocBytes)
import           Foreign.Marshal.Array  (peekArray, pokeArray)
import           Foreign.Storable       (peek, sizeOf)
import           HalfSpaces.CHalfSpaces
import           HalfSpaces.Constraint  (Constraint)
import           HalfSpaces.Internal    (normalizeConstraints)
import           HalfSpaces.ToySolver

hsintersections' :: [[Double]]     -- halfspaces
                 -> [Double]       -- interior point
                 -> Bool           -- print to stdout
                 -> IO [[Double]]
hsintersections' halfspaces ipoint stdout = do
  let n     = length halfspaces
      dim   = length ipoint
  unless (all (== dim+1) (map length halfspaces)) $
    error "the points must have the same dimension"
  when (dim < 2) $
    error "dimension must be at least 2"
  when (n <= dim) $
    error "insufficient number of halfspaces"
  hsPtr <- mallocBytes (n * (dim+1) * sizeOf (undefined :: CDouble))
  pokeArray hsPtr (concatMap (map realToFrac) halfspaces)
  ipointPtr <- mallocBytes (dim * sizeOf (undefined :: CDouble))
  pokeArray ipointPtr (map realToFrac ipoint)
  exitcodePtr <- mallocBytes (sizeOf (undefined :: CUInt))
  nintersectionsPtr <- mallocBytes (sizeOf (undefined :: CUInt))
  resultPtr <- c_intersections hsPtr ipointPtr
               (fromIntegral dim) (fromIntegral n)
               nintersectionsPtr exitcodePtr (fromIntegral $ fromEnum stdout)
  exitcode <- peek exitcodePtr
  free exitcodePtr
  free hsPtr
  if exitcode /= 0
    then do
      free resultPtr
      free nintersectionsPtr
      error $ "qhull returned an error (code " ++ show exitcode ++ ")"
    else do
      nintersections <- (<$!>) fromIntegral (peek nintersectionsPtr)
      result <- (<$!>) (map (map realToFrac))
                       ((=<<) (mapM (peekArray dim))
                             (peekArray nintersections resultPtr))
      free resultPtr
      free nintersectionsPtr
      return result

hsintersections :: [Constraint] -> Bool -> IO [[Double]]
hsintersections constraints stdout = do
  let halfspacesMatrix = normalizeConstraints constraints
  ipoint <- (<$!>) (map realToFrac) (interiorPoint constraints)
  hsintersections' halfspacesMatrix ipoint stdout

cubeConstraints' :: [[Double]]
cubeConstraints' = [[ 1, 0, 0,-1]
                   ,[-1, 0, 0,-1]
                   ,[ 0, 1, 0,-1]
                   ,[ 0,-1, 0,-1]
                   ,[ 0, 0, 1,-1]
                   ,[ 0, 0,-1,-1]]