module Numeric.GSL.Histogram (
Histogram
, fromRanges, fromLimits
, addList, addVector, addListWeighted, addVectorWeighted
, toVectors
, getBin, getRange
, getMax, getMin, getBins
, find
, maxVal, maxBin, minVal, minBin
, mean, stddev, sum
, equalBins
, add, subtract, multiply, divide, shift, scale
, fwriteHistogram, freadHistogram, fprintfHistogram, fscanfHistogram
, HistogramPDF
, fromHistogram
, sample
) where
import Data.Packed.Vector
import Data.Packed.Development
import Foreign hiding(shift)
import Foreign.C.Types(CInt,CChar)
import Foreign.C.String(newCString)
import Prelude hiding(subtract,sum)
data Hist
type HistHandle = Ptr Hist
data Histogram = H { hdim :: !Int
, hist :: !(ForeignPtr Hist) }
data PDF
type PDFHandle = Ptr PDF
data HistogramPDF = P { pdf :: !(ForeignPtr PDF)}
instance Eq Histogram where
(==) = equalBins
foreign import ccall "gsl-histogram.h gsl_histogram_alloc" histogram_new :: CInt -> IO HistHandle
foreign import ccall "gsl-histogram.h &gsl_histogram_free" histogram_free :: FunPtr (HistHandle -> IO ())
fromRangesIO :: Vector Double -> IO Histogram
fromRangesIO v = do
let sz = fromIntegral $ dim v 1
h <- histogram_new sz
h' <- newForeignPtr histogram_free h
app1 (\d p -> withForeignPtr h' $ \f -> histogram_set_ranges f (fromIntegral d) p) vec v "fromRanges"
return $ H (fromIntegral sz) h'
fromLimitsIO :: Int -> (Double,Double) -> IO Histogram
fromLimitsIO n (l,u) = do
h <- histogram_new (fromIntegral n)
h' <- newForeignPtr histogram_free h
check "set_ranges_uniform" $ withForeignPtr h' (\f -> histogram_set_ranges_uniform f l u)
return $ H n h'
foreign import ccall "gsl-histogram.h gsl_histogram_set_ranges" histogram_set_ranges :: HistHandle -> CInt -> Ptr Double -> IO CInt
foreign import ccall "gsl-histogram.h gsl_histogram_set_ranges_uniform" histogram_set_ranges_uniform :: HistHandle -> Double -> Double -> IO CInt
fromRanges :: Vector Double
-> Vector Double
-> Histogram
fromRanges r d = unsafePerformIO $ do
h <- fromRangesIO r
incrementVectorIO h d
return h
fromLimits :: Int
-> (Double,Double)
-> Vector Double
-> Histogram
fromLimits n r d = unsafePerformIO $ do
h <- fromLimitsIO n r
incrementVectorIO h d
return h
toVectors :: Histogram -> (Vector Double,Vector Double)
toVectors (H b h) = unsafePerformIO $ do
rs <- createVector (b+1)
bs <- createVector b
app2 (\s1 p1 s2 p2 -> withForeignPtr h $ \f -> histogram_to_vectors f s1 p1 s2 p2) vec rs vec bs "toVectors"
return (rs,bs)
foreign import ccall "gsl-histogram.h to_vectors" histogram_to_vectors :: HistHandle -> CInt -> Ptr Double -> CInt -> Ptr Double -> IO CInt
cloneHistogram :: Histogram -> IO Histogram
cloneHistogram (H b h) = do
h' <- withForeignPtr h histogram_clone
h'' <- newForeignPtr histogram_free h'
return $ H b h''
foreign import ccall "gsl-histogram.h gsl_histogram_clone" histogram_clone :: HistHandle -> IO HistHandle
addList :: Histogram -> [Double] -> Histogram
addList h xs = unsafePerformIO $ do
h' <- cloneHistogram h
incrementListIO h' xs
return h'
addVector :: Histogram -> Vector Double -> Histogram
addVector h v = unsafePerformIO $ do
h' <- cloneHistogram h
incrementVectorIO h' v
return h'
addListWeighted :: Histogram -> [(Double,Double)] -> Histogram
addListWeighted h xs = unsafePerformIO $ do
h' <- cloneHistogram h
accumulateListIO h' xs
return h'
addVectorWeighted :: Histogram -> Vector Double -> Vector Double -> Histogram
addVectorWeighted h v w = unsafePerformIO $ do
h' <- cloneHistogram h
accumulateVectorIO h' v w
return h'
incrementIO :: Histogram -> Double -> IO ()
incrementIO (H _ h) x = withForeignPtr h (\f -> check "increment" $ histogram_increment f x)
incrementListIO :: Histogram -> [Double] -> IO ()
incrementListIO (H _ h) xs = withForeignPtr h (\f -> mapM_ (histogram_increment f) xs)
incrementVectorIO :: Histogram -> Vector Double -> IO ()
incrementVectorIO (H _ h) v = do
app1 (\s p -> withForeignPtr h (\f -> histogram_increment_vector f s p)) vec v "incrementVector"
return ()
accumulateIO :: Histogram -> Double -> Double -> IO ()
accumulateIO (H _ h) x w = withForeignPtr h (\f -> check "accumulate" $ histogram_accumulate f x w)
accumulateListIO :: Histogram -> [(Double,Double)] -> IO ()
accumulateListIO (H _ h) xs = do
withForeignPtr h (\f -> mapM_ (\(x,w) -> histogram_accumulate f x w) xs)
return ()
accumulateVectorIO :: Histogram -> Vector Double -> Vector Double -> IO ()
accumulateVectorIO (H _ h) v w = do
app2 (\s1 p1 s2 p2 -> withForeignPtr h (\f -> histogram_accumulate_vector f s1 p1 s2 p2)) vec v vec w "accumulateVector"
return ()
getBin :: Histogram -> Int -> Double
getBin (H _ h) b = unsafePerformIO $ do
withForeignPtr h (\f -> histogram_get f (fromIntegral b))
getRange :: Histogram -> Int -> (Double,Double)
getRange (H _ h) b = unsafePerformIO $ do
alloca $ \l ->
alloca $ \u -> do
check "get_range" $ withForeignPtr h (\f -> histogram_get_range f (fromIntegral b) l u)
l' <- peek l
u' <- peek u
return (l',u')
getMax :: Histogram -> Double
getMax (H _ h) = unsafePerformIO $ withForeignPtr h histogram_max
getMin :: Histogram -> Double
getMin (H _ h) = unsafePerformIO $ withForeignPtr h histogram_min
getBins :: Histogram -> Int
getBins (H b _) = b
reset :: Histogram -> IO ()
reset (H _ h) = withForeignPtr h histogram_reset
foreign import ccall "gsl-histogram.h gsl_histogram_increment" histogram_increment :: HistHandle -> Double -> IO CInt
foreign import ccall "gsl-histogram.h gsl_histogram_accumulate" histogram_accumulate :: HistHandle -> Double -> Double -> IO CInt
foreign import ccall "gsl-histogram.h gsl_histogram_get" histogram_get :: HistHandle -> CInt -> IO Double
foreign import ccall "gsl-histogram.h gsl_histogram_get_range" histogram_get_range :: HistHandle -> CInt -> Ptr Double -> Ptr Double -> IO CInt
foreign import ccall "gsl-histogram.h gsl_histogram_max" histogram_max :: HistHandle -> IO Double
foreign import ccall "gsl-histogram.h gsl_histogram_min" histogram_min :: HistHandle -> IO Double
foreign import ccall "gsl-histogram.h gsl_histogram_bins" histogram_bins :: HistHandle -> IO Int
foreign import ccall "gsl-histogram.h gsl_histogram_reset" histogram_reset :: HistHandle -> IO ()
foreign import ccall "histogram-aux.h increment_vector" histogram_increment_vector :: HistHandle -> CInt -> Ptr Double -> IO CInt
foreign import ccall "histogram-aux.h accumulate_vector" histogram_accumulate_vector :: HistHandle -> CInt -> Ptr Double -> CInt -> Ptr Double -> IO CInt
find :: Histogram -> Double -> Maybe Int
find (H _ h) x = unsafePerformIO $ do
alloca $ \b -> do
err <- withForeignPtr h (\f -> histogram_find f x b)
if err == 0
then do
b' <- peek b
return $ Just $ fromIntegral b'
else return Nothing
foreign import ccall "gsl-histogram.h gsl_histogram_find" histogram_find :: HistHandle -> Double -> Ptr CInt -> IO CInt
maxVal :: Histogram -> Double
maxVal (H _ h) = unsafePerformIO $ withForeignPtr h histogram_max_val
maxBin :: Histogram -> Int
maxBin (H _ h) = unsafePerformIO $ do
i <- withForeignPtr h histogram_max_bin
return $ fromIntegral i
minVal :: Histogram -> Double
minVal (H _ h) = unsafePerformIO $ withForeignPtr h histogram_min_val
minBin :: Histogram -> Int
minBin (H _ h) = unsafePerformIO $ do
i <- withForeignPtr h histogram_min_bin
return $ fromIntegral i
mean :: Histogram -> Double
mean (H _ h) = unsafePerformIO $ withForeignPtr h histogram_mean
stddev :: Histogram -> Double
stddev (H _ h) = unsafePerformIO $ withForeignPtr h histogram_sigma
sum :: Histogram -> Double
sum (H _ h) = unsafePerformIO $ withForeignPtr h histogram_sum
foreign import ccall "gsl-histogram.h gsl_histogram_max_val" histogram_max_val :: HistHandle -> IO Double
foreign import ccall "gsl-histogram.h gsl_histogram_max_bin" histogram_max_bin :: HistHandle -> IO CInt
foreign import ccall "gsl-histogram.h gsl_histogram_min_val" histogram_min_val :: HistHandle -> IO Double
foreign import ccall "gsl-histogram.h gsl_histogram_min_bin" histogram_min_bin :: HistHandle -> IO CInt
foreign import ccall "gsl-histogram.h gsl_histogram_mean" histogram_mean :: HistHandle -> IO Double
foreign import ccall "gsl-histogram.h gsl_histogram_sigma" histogram_sigma :: HistHandle -> IO Double
foreign import ccall "gsl-histogram.h gsl_histogram_sum" histogram_sum :: HistHandle -> IO Double
equalBins :: Histogram -> Histogram -> Bool
equalBins (H _ h1) (H _ h2) = unsafePerformIO $ do
i <- withForeignPtr h1 $ \p1 -> do
withForeignPtr h2 $ \p2 -> histogram_equal_bins p1 p2
if (fromIntegral i) == (1 :: Int)
then return True
else return False
add :: Histogram -> Histogram -> Histogram
add d (H _ s) = unsafePerformIO $ do
h@(H _ d') <- cloneHistogram d
check "add" $
withForeignPtr d' $ \dp ->
withForeignPtr s $ \sp -> histogram_add dp sp
return h
subtract :: Histogram -> Histogram -> Histogram
subtract d (H _ s) = unsafePerformIO $ do
h@(H _ d') <- cloneHistogram d
check "subtract" $
withForeignPtr d' $ \dp ->
withForeignPtr s $ \sp -> histogram_sub dp sp
return h
multiply :: Histogram -> Histogram -> Histogram
multiply d (H _ s) = unsafePerformIO $ do
h@(H _ d') <- cloneHistogram d
check "multiply" $
withForeignPtr d' $ \dp ->
withForeignPtr s $ \sp -> histogram_mul dp sp
return h
divide :: Histogram -> Histogram -> Histogram
divide d (H _ s) = unsafePerformIO $ do
h@(H _ d') <- cloneHistogram d
check "divide" $
withForeignPtr d' $ \dp ->
withForeignPtr s $ \sp -> histogram_div dp sp
return h
scale :: Histogram -> Double -> Histogram
scale d s = unsafePerformIO $ do
h@(H _ d') <- cloneHistogram d
check "scale" $
withForeignPtr d' $ (\f -> histogram_scale f s)
return h
shift :: Histogram -> Double -> Histogram
shift d s = unsafePerformIO $ do
h@(H _ d') <- cloneHistogram d
check "shift" $
withForeignPtr d' $ (\f -> histogram_shift f s)
return h
foreign import ccall "gsl-histogram.h gsl_histogram_equal_bins_p" histogram_equal_bins :: HistHandle -> HistHandle -> IO CInt
foreign import ccall "gsl-histogram.h gsl_histogram_add" histogram_add :: HistHandle -> HistHandle -> IO CInt
foreign import ccall "gsl-histogram.h gsl_histogram_sub" histogram_sub :: HistHandle -> HistHandle -> IO CInt
foreign import ccall "gsl-histogram.h gsl_histogram_mul" histogram_mul :: HistHandle -> HistHandle -> IO CInt
foreign import ccall "gsl-histogram.h gsl_histogram_div" histogram_div :: HistHandle -> HistHandle -> IO CInt
foreign import ccall "gsl-histogram.h gsl_histogram_scale" histogram_scale :: HistHandle -> Double -> IO CInt
foreign import ccall "gsl-histogram.h gsl_histogram_shift" histogram_shift :: HistHandle -> Double -> IO CInt
fwriteHistogram :: FilePath -> Histogram -> IO ()
fwriteHistogram fn (H _ h) = do
cn <- newCString fn
check "fwriteHistogram" $
withForeignPtr h $ histogram_fwrite cn
free cn
freadHistogram :: FilePath -> Int -> IO Histogram
freadHistogram fn b = do
h <- histogram_new (fromIntegral b)
h' <- newForeignPtr histogram_free h
cn <- newCString fn
check "freadHistogram" $
withForeignPtr h' $ histogram_fread cn
return $ H b h'
fprintfHistogram :: FilePath -> String -> String -> Histogram -> IO ()
fprintfHistogram fn fr fb (H _ h) = do
cn <- newCString fn
cr <- newCString fr
cb <- newCString fb
check "fprintfHistogram" $
withForeignPtr h $ histogram_fprintf cn cr cb
free cn
free cr
free cb
return ()
fscanfHistogram :: FilePath -> Int -> IO Histogram
fscanfHistogram fn b = do
h <- histogram_new (fromIntegral b)
h' <- newForeignPtr histogram_free h
cn <- newCString fn
check "fscanfHistogram" $
withForeignPtr h' $ histogram_fscanf cn
return $ H b h'
foreign import ccall "histogram-aux.h hist_fwrite" histogram_fwrite :: Ptr CChar -> HistHandle -> IO CInt
foreign import ccall "histogram-aux.h hist_fread" histogram_fread :: Ptr CChar -> HistHandle -> IO CInt
foreign import ccall "histogram-aux.h hist_fprintf" histogram_fprintf :: Ptr CChar -> Ptr CChar -> Ptr CChar -> HistHandle -> IO CInt
foreign import ccall "histogram-aux.h hist_fscanf" histogram_fscanf :: Ptr CChar -> HistHandle -> IO CInt
foreign import ccall "gsl-histogram.h gsl_histogram_pdf_alloc" histogram_pdf_new :: CInt -> IO PDFHandle
foreign import ccall "gsl-histogram.h &gsl_histogram_pdf_free" histogram_pdf_free :: FunPtr (PDFHandle -> IO ())
fromHistogram :: Histogram -> HistogramPDF
fromHistogram (H b h) = unsafePerformIO $ do
p <- histogram_pdf_new $ fromIntegral b
p' <- newForeignPtr histogram_pdf_free p
withForeignPtr p' $ \p'' ->
withForeignPtr h $ \h' -> check "pdf_init" $ histogram_pdf_init p'' h'
return $ P p'
sample :: HistogramPDF -> Double
sample (P p) = unsafePerformIO $ withForeignPtr p $ \p' -> histogram_pdf_sample p'
foreign import ccall "gsl-histogram.h gsl_histogram_pdf_init" histogram_pdf_init :: PDFHandle -> HistHandle -> IO CInt
foreign import ccall "gsl-histogram.h gsl_histogram_pdf_sample" histogram_pdf_sample :: PDFHandle -> IO Double