summaryrefslogtreecommitdiff
path: root/packages/base/src
diff options
context:
space:
mode:
authorAlberto Ruiz <aruiz@um.es>2015-06-05 16:53:45 +0200
committerAlberto Ruiz <aruiz@um.es>2015-06-05 16:53:45 +0200
commita5d14b70e70a93b2dec29fc0dfa7940488dc264a (patch)
tree2e1d698ca261a1ec492a2b47680a9de9723b482c /packages/base/src
parentba04d65298266a2f6a37061bedaca4ea3cf7fae6 (diff)
move internal vector
Diffstat (limited to 'packages/base/src')
-rw-r--r--packages/base/src/Data/Packed/Vector.hs125
-rw-r--r--packages/base/src/Internal/Vector.hs (renamed from packages/base/src/Data/Packed/Internal/Vector.hs)317
2 files changed, 134 insertions, 308 deletions
diff --git a/packages/base/src/Data/Packed/Vector.hs b/packages/base/src/Data/Packed/Vector.hs
deleted file mode 100644
index 2104f52..0000000
--- a/packages/base/src/Data/Packed/Vector.hs
+++ /dev/null
@@ -1,125 +0,0 @@
1{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE CPP #-}
3-----------------------------------------------------------------------------
4-- |
5-- Module : Data.Packed.Vector
6-- Copyright : (c) Alberto Ruiz 2007-10
7-- License : BSD3
8-- Maintainer : Alberto Ruiz
9-- Stability : provisional
10--
11-- 1D arrays suitable for numeric computations using external libraries.
12--
13-- This module provides basic functions for manipulation of structure.
14--
15-----------------------------------------------------------------------------
16{-# OPTIONS_HADDOCK hide #-}
17
18module Data.Packed.Vector (
19 Vector,
20 fromList, (|>), toList, buildVector,
21 dim, (@>),
22 subVector, takesV, vjoin, join,
23 mapVector, mapVectorWithIndex, zipVector, zipVectorWith, unzipVector, unzipVectorWith,
24 mapVectorM, mapVectorM_, mapVectorWithIndexM, mapVectorWithIndexM_,
25 foldLoop, foldVector, foldVectorG, foldVectorWithIndex,
26 toByteString, fromByteString
27) where
28
29import Data.Packed.Internal.Vector
30import Foreign.Storable
31
32-------------------------------------------------------------------
33
34#ifdef BINARY
35
36import Data.Binary
37import Control.Monad(replicateM)
38
39import Data.ByteString.Internal as BS
40import Foreign.ForeignPtr(castForeignPtr)
41import Data.Vector.Storable.Internal(updPtr)
42import Foreign.Ptr(plusPtr)
43
44
45-- a 64K cache, with a Double taking 13 bytes in Bytestring,
46-- implies a chunk size of 5041
47chunk :: Int
48chunk = 5000
49
50chunks :: Int -> [Int]
51chunks d = let c = d `div` chunk
52 m = d `mod` chunk
53 in if m /= 0 then reverse (m:(replicate c chunk)) else (replicate c chunk)
54
55putVector v = mapM_ put $! toList v
56
57getVector d = do
58 xs <- replicateM d get
59 return $! fromList xs
60
61--------------------------------------------------------------------------------
62
63toByteString :: Storable t => Vector t -> ByteString
64toByteString v = BS.PS (castForeignPtr fp) (sz*o) (sz * dim v)
65 where
66 (fp,o,_n) = unsafeToForeignPtr v
67 sz = sizeOf (v@>0)
68
69
70fromByteString :: Storable t => ByteString -> Vector t
71fromByteString (BS.PS fp o n) = r
72 where
73 r = unsafeFromForeignPtr (castForeignPtr (updPtr (`plusPtr` o) fp)) 0 n'
74 n' = n `div` sz
75 sz = sizeOf (r@>0)
76
77--------------------------------------------------------------------------------
78
79instance (Binary a, Storable a) => Binary (Vector a) where
80
81 put v = do
82 let d = dim v
83 put d
84 mapM_ putVector $! takesV (chunks d) v
85
86 -- put = put . v2bs
87
88 get = do
89 d <- get
90 vs <- mapM getVector $ chunks d
91 return $! vjoin vs
92
93 -- get = fmap bs2v get
94
95#endif
96
97
98-------------------------------------------------------------------
99
100{- | creates a Vector of the specified length using the supplied function to
101 to map the index to the value at that index.
102
103@> buildVector 4 fromIntegral
1044 |> [0.0,1.0,2.0,3.0]@
105
106-}
107buildVector :: Storable a => Int -> (Int -> a) -> Vector a
108buildVector len f =
109 fromList $ map f [0 .. (len - 1)]
110
111
112-- | zip for Vectors
113zipVector :: (Storable a, Storable b, Storable (a,b)) => Vector a -> Vector b -> Vector (a,b)
114zipVector = zipVectorWith (,)
115
116-- | unzip for Vectors
117unzipVector :: (Storable a, Storable b, Storable (a,b)) => Vector (a,b) -> (Vector a,Vector b)
118unzipVector = unzipVectorWith id
119
120-------------------------------------------------------------------
121
122{-# DEPRECATED join "use vjoin or Data.Vector.concat" #-}
123join :: Storable t => [Vector t] -> Vector t
124join = vjoin
125
diff --git a/packages/base/src/Data/Packed/Internal/Vector.hs b/packages/base/src/Internal/Vector.hs
index 8cb77b0..27ee13c 100644
--- a/packages/base/src/Data/Packed/Internal/Vector.hs
+++ b/packages/base/src/Internal/Vector.hs
@@ -1,62 +1,47 @@
1{-# LANGUAGE MagicHash, CPP, UnboxedTuples, BangPatterns, FlexibleContexts #-} 1{-# LANGUAGE MagicHash, CPP, UnboxedTuples, BangPatterns, FlexibleContexts #-}
2{-# LANGUAGE TypeSynonymInstances #-}
3
4
2-- | 5-- |
3-- Module : Data.Packed.Internal.Vector 6-- Module : Internal.Vector
4-- Copyright : (c) Alberto Ruiz 2007 7-- Copyright : (c) Alberto Ruiz 2007-15
5-- License : BSD3 8-- License : BSD3
6-- Maintainer : Alberto Ruiz 9-- Maintainer : Alberto Ruiz
7-- Stability : provisional 10-- Stability : provisional
8-- 11--
9-- Vector implementation
10--
11--------------------------------------------------------------------------------
12 12
13module Data.Packed.Internal.Vector ( 13module Internal.Vector where
14 Vector, dim, 14
15 fromList, toList, (|>), 15import Internal.Tools
16 vjoin, (@>), safe, at, at', subVector, takesV, 16import Foreign.Marshal.Array ( peekArray, copyArray, advancePtr )
17 mapVector, mapVectorWithIndex, zipVectorWith, unzipVectorWith, 17import Foreign.ForeignPtr ( ForeignPtr, castForeignPtr )
18 mapVectorM, mapVectorM_, mapVectorWithIndexM, mapVectorWithIndexM_, 18import Foreign.Ptr ( Ptr )
19 foldVector, foldVectorG, foldLoop, foldVectorWithIndex, 19import Foreign.Storable
20 createVector, vec, 20 ( Storable, peekElemOff, pokeElemOff, sizeOf )
21 asComplex, asReal, float2DoubleV, double2FloatV, double2IntV, int2DoubleV, float2IntV, int2floatV, 21import Foreign.C.Types ( CInt )
22 stepF, stepD, stepI, condF, condD, condI, 22import Data.Complex ( Complex )
23 conjugateQ, conjugateC, 23import System.IO.Unsafe ( unsafePerformIO )
24 cloneVector, 24import GHC.ForeignPtr ( mallocPlainForeignPtrBytes )
25 unsafeToForeignPtr, 25import GHC.Base ( realWorld#, IO(IO), when )
26 unsafeFromForeignPtr, 26import qualified Data.Vector.Storable as Vector
27 unsafeWith, 27 ( Vector, slice, length )
28 CInt, I 28import Data.Vector.Storable
29) where 29 ( fromList, unsafeToForeignPtr, unsafeFromForeignPtr, unsafeWith )
30 30
31import Data.Packed.Internal.Common 31
32import Data.Packed.Internal.Signatures 32#ifdef BINARY
33import Foreign.Marshal.Array(peekArray, copyArray, advancePtr) 33
34import Foreign.ForeignPtr(ForeignPtr, castForeignPtr) 34import Data.Binary
35import Foreign.Ptr(Ptr) 35import Control.Monad(replicateM)
36import Foreign.Storable(Storable, peekElemOff, pokeElemOff, sizeOf) 36import qualified Data.ByteString.Internal as BS
37import Foreign.C.Types 37import Data.Vector.Storable.Internal(updPtr)
38import Data.Complex 38import Foreign.Ptr(plusPtr)
39import System.IO.Unsafe(unsafePerformIO)
40
41#if __GLASGOW_HASKELL__ >= 605
42import GHC.ForeignPtr (mallocPlainForeignPtrBytes)
43#else
44import Foreign.ForeignPtr (mallocForeignPtrBytes)
45#endif
46 39
47import GHC.Base
48#if __GLASGOW_HASKELL__ < 612
49import GHC.IOBase hiding (liftIO)
50#endif 40#endif
51 41
52import qualified Data.Vector.Storable as Vector
53import Data.Vector.Storable(Vector,
54 fromList,
55 unsafeToForeignPtr,
56 unsafeFromForeignPtr,
57 unsafeWith)
58 42
59type I = CInt 43
44type Vector = Vector.Vector
60 45
61-- | Number of elements 46-- | Number of elements
62dim :: (Storable t) => Vector t -> Int 47dim :: (Storable t) => Vector t -> Int
@@ -86,11 +71,7 @@ createVector n = do
86 -- 71 --
87 doMalloc :: Storable b => b -> IO (ForeignPtr b) 72 doMalloc :: Storable b => b -> IO (ForeignPtr b)
88 doMalloc dummy = do 73 doMalloc dummy = do
89#if __GLASGOW_HASKELL__ >= 605
90 mallocPlainForeignPtrBytes (n * sizeOf dummy) 74 mallocPlainForeignPtrBytes (n * sizeOf dummy)
91#else
92 mallocForeignPtrBytes (n * sizeOf dummy)
93#endif
94 75
95{- | creates a Vector from a list: 76{- | creates a Vector from a list:
96 77
@@ -116,7 +97,7 @@ toList :: Storable a => Vector a -> [a]
116toList v = safeRead v $ peekArray (dim v) 97toList v = safeRead v $ peekArray (dim v)
117 98
118{- | Create a vector from a list of elements and explicit dimension. The input 99{- | Create a vector from a list of elements and explicit dimension. The input
119 list is explicitly truncated if it is too long, so it may safely 100 list is truncated if it is too long, so it may safely
120 be used, for instance, with infinite lists. 101 be used, for instance, with infinite lists.
121 102
122>>> 5 |> [1..] 103>>> 5 |> [1..]
@@ -125,36 +106,16 @@ fromList [1.0,2.0,3.0,4.0,5.0]
125-} 106-}
126(|>) :: (Storable a) => Int -> [a] -> Vector a 107(|>) :: (Storable a) => Int -> [a] -> Vector a
127infixl 9 |> 108infixl 9 |>
128n |> l = if length l' == n 109n |> l
129 then fromList l' 110 | length l' == n = fromList l'
130 else error "list too short for |>" 111 | otherwise = error "list too short for |>"
131 where l' = take n l 112 where
132 113 l' = take n l
133
134-- | access to Vector elements without range checking
135at' :: Storable a => Vector a -> Int -> a
136at' v n = safeRead v $ flip peekElemOff n
137{-# INLINE at' #-}
138 114
139--
140-- turn off bounds checking with -funsafe at configure time.
141-- ghc will optimise away the salways true case at compile time.
142--
143#if defined(UNSAFE)
144safe :: Bool
145safe = False
146#else
147safe = True
148#endif
149 115
150-- | access to Vector elements with range checking. 116-- | Create a vector of indexes, useful for matrix extraction using '??'
151at :: Storable a => Vector a -> Int -> a 117idxs :: [Int] -> Vector I
152at v n 118idxs js = fromList (map fromIntegral js) :: Vector I
153 | safe = if n >= 0 && n < dim v
154 then at' v n
155 else error "vector index out of range"
156 | otherwise = at' v n
157{-# INLINE at #-}
158 119
159{- | takes a number of consecutive elements from a Vector 120{- | takes a number of consecutive elements from a Vector
160 121
@@ -169,6 +130,8 @@ subVector :: Storable t => Int -- ^ index of the starting element
169subVector = Vector.slice 130subVector = Vector.slice
170 131
171 132
133
134
172{- | Reads a vector position: 135{- | Reads a vector position:
173 136
174>>> fromList [0..9] @> 7 137>>> fromList [0..9] @> 7
@@ -177,8 +140,15 @@ subVector = Vector.slice
177-} 140-}
178(@>) :: Storable t => Vector t -> Int -> t 141(@>) :: Storable t => Vector t -> Int -> t
179infixl 9 @> 142infixl 9 @>
180(@>) = at 143v @> n
144 | n >= 0 && n < dim v = at' v n
145 | otherwise = error "vector index out of range"
146{-# INLINE (@>) #-}
181 147
148-- | access to Vector elements without range checking
149at' :: Storable a => Vector a -> Int -> a
150at' v n = safeRead v $ flip peekElemOff n
151{-# INLINE at' #-}
182 152
183{- | concatenate a list of vectors 153{- | concatenate a list of vectors
184 154
@@ -227,108 +197,8 @@ asComplex :: (RealFloat a, Storable a) => Vector a -> Vector (Complex a)
227asComplex v = unsafeFromForeignPtr (castForeignPtr fp) (i `div` 2) (n `div` 2) 197asComplex v = unsafeFromForeignPtr (castForeignPtr fp) (i `div` 2) (n `div` 2)
228 where (fp,i,n) = unsafeToForeignPtr v 198 where (fp,i,n) = unsafeToForeignPtr v
229 199
230---------------------------------------------------------------
231
232float2DoubleV :: Vector Float -> Vector Double
233float2DoubleV = tog c_float2double
234
235double2FloatV :: Vector Double -> Vector Float
236double2FloatV = tog c_double2float
237
238double2IntV :: Vector Double -> Vector CInt
239double2IntV = tog c_double2int
240
241int2DoubleV :: Vector CInt -> Vector Double
242int2DoubleV = tog c_int2double
243
244float2IntV :: Vector Float -> Vector CInt
245float2IntV = tog c_float2int
246
247int2floatV :: Vector CInt -> Vector Float
248int2floatV = tog c_int2float
249
250
251tog f v = unsafePerformIO $ do
252 r <- createVector (dim v)
253 app2 f vec v vec r "tog"
254 return r
255
256foreign import ccall unsafe "float2double" c_float2double :: TFV
257foreign import ccall unsafe "double2float" c_double2float :: TVF
258foreign import ccall unsafe "int2double" c_int2double :: CV CInt (CV Double (IO CInt))
259foreign import ccall unsafe "double2int" c_double2int :: CV Double (CV CInt (IO CInt))
260foreign import ccall unsafe "int2float" c_int2float :: CV CInt (CV Float (IO CInt))
261foreign import ccall unsafe "float2int" c_float2int :: CV Float (CV CInt (IO CInt))
262
263
264---------------------------------------------------------------
265
266step f v = unsafePerformIO $ do
267 r <- createVector (dim v)
268 app2 f vec v vec r "step"
269 return r
270
271stepD :: Vector Double -> Vector Double
272stepD = step c_stepD
273
274stepF :: Vector Float -> Vector Float
275stepF = step c_stepF
276
277stepI :: Vector CInt -> Vector CInt
278stepI = step c_stepI
279
280foreign import ccall unsafe "stepF" c_stepF :: TFF
281foreign import ccall unsafe "stepD" c_stepD :: TVV
282foreign import ccall unsafe "stepI" c_stepI :: CV CInt (CV CInt (IO CInt))
283
284---------------------------------------------------------------
285
286condF :: Vector Float -> Vector Float -> Vector Float -> Vector Float -> Vector Float -> Vector Float
287condF = condg c_condF
288
289condD :: Vector Double -> Vector Double -> Vector Double -> Vector Double -> Vector Double -> Vector Double
290condD = condg c_condD
291
292condI :: Vector CInt -> Vector CInt -> Vector CInt -> Vector CInt -> Vector CInt -> Vector CInt
293condI = condg c_condI
294
295
296condg f x y l e g = unsafePerformIO $ do
297 r <- createVector (dim x)
298 app6 f vec x vec y vec l vec e vec g vec r "cond"
299 return r
300
301
302foreign import ccall unsafe "condF" c_condF :: CInt -> PF -> CInt -> PF -> CInt -> PF -> TFFF
303foreign import ccall unsafe "condD" c_condD :: CInt -> PD -> CInt -> PD -> CInt -> PD -> TVVV
304foreign import ccall unsafe "condI" c_condI :: CV CInt (CV CInt (CV CInt (CV CInt (CV CInt (CV CInt (IO CInt))))))
305
306-------------------------------------------------------------------------------- 200--------------------------------------------------------------------------------
307 201
308conjugateAux fun x = unsafePerformIO $ do
309 v <- createVector (dim x)
310 app2 fun vec x vec v "conjugateAux"
311 return v
312
313conjugateQ :: Vector (Complex Float) -> Vector (Complex Float)
314conjugateQ = conjugateAux c_conjugateQ
315foreign import ccall unsafe "conjugateQ" c_conjugateQ :: TQVQV
316
317conjugateC :: Vector (Complex Double) -> Vector (Complex Double)
318conjugateC = conjugateAux c_conjugateC
319foreign import ccall unsafe "conjugateC" c_conjugateC :: TCVCV
320
321--------------------------------------------------------------------------------
322
323cloneVector :: Storable t => Vector t -> IO (Vector t)
324cloneVector v = do
325 let n = dim v
326 r <- createVector n
327 let f _ s _ d = copyArray d s n >> return 0
328 app2 f vec v vec r "cloneVector"
329 return r
330
331------------------------------------------------------------------
332 202
333-- | map on Vectors 203-- | map on Vectors
334mapVector :: (Storable a, Storable b) => (a-> b) -> Vector a -> Vector b 204mapVector :: (Storable a, Storable b) => (a-> b) -> Vector a -> Vector b
@@ -406,7 +276,7 @@ foldLoop f s0 d = go (d - 1) s0
406 go !j !s = go (j - 1) (f j s) 276 go !j !s = go (j - 1) (f j s)
407 277
408foldVectorG f s0 v = foldLoop g s0 (dim v) 278foldVectorG f s0 v = foldLoop g s0 (dim v)
409 where g !k !s = f k (at' v) s 279 where g !k !s = f k (safeRead v . flip peekElemOff) s
410 {-# INLINE g #-} -- Thanks to Ryan Ingram (http://permalink.gmane.org/gmane.comp.lang.haskell.cafe/46479) 280 {-# INLINE g #-} -- Thanks to Ryan Ingram (http://permalink.gmane.org/gmane.comp.lang.haskell.cafe/46479)
411{-# INLINE foldVectorG #-} 281{-# INLINE foldVectorG #-}
412 282
@@ -493,4 +363,85 @@ mapVectorWithIndex f v = unsafePerformIO $ do
493 return w 363 return w
494{-# INLINE mapVectorWithIndex #-} 364{-# INLINE mapVectorWithIndex #-}
495 365
366--------------------------------------------------------------------------------
367
368
369#ifdef BINARY
370
371-- a 64K cache, with a Double taking 13 bytes in Bytestring,
372-- implies a chunk size of 5041
373chunk :: Int
374chunk = 5000
375
376chunks :: Int -> [Int]
377chunks d = let c = d `div` chunk
378 m = d `mod` chunk
379 in if m /= 0 then reverse (m:(replicate c chunk)) else (replicate c chunk)
380
381putVector v = mapM_ put $! toList v
382
383getVector d = do
384 xs <- replicateM d get
385 return $! fromList xs
386
387--------------------------------------------------------------------------------
388
389toByteString :: Storable t => Vector t -> BS.ByteString
390toByteString v = BS.PS (castForeignPtr fp) (sz*o) (sz * dim v)
391 where
392 (fp,o,_n) = unsafeToForeignPtr v
393 sz = sizeOf (v@>0)
394
395
396fromByteString :: Storable t => BS.ByteString -> Vector t
397fromByteString (BS.PS fp o n) = r
398 where
399 r = unsafeFromForeignPtr (castForeignPtr (updPtr (`plusPtr` o) fp)) 0 n'
400 n' = n `div` sz
401 sz = sizeOf (r@>0)
402
403--------------------------------------------------------------------------------
404
405instance (Binary a, Storable a) => Binary (Vector a) where
406
407 put v = do
408 let d = dim v
409 put d
410 mapM_ putVector $! takesV (chunks d) v
411
412 -- put = put . v2bs
413
414 get = do
415 d <- get
416 vs <- mapM getVector $ chunks d
417 return $! vjoin vs
418
419 -- get = fmap bs2v get
420
421#endif
422
423
424-------------------------------------------------------------------
425
426{- | creates a Vector of the specified length using the supplied function to
427 to map the index to the value at that index.
428
429@> buildVector 4 fromIntegral
4304 |> [0.0,1.0,2.0,3.0]@
431
432-}
433buildVector :: Storable a => Int -> (Int -> a) -> Vector a
434buildVector len f =
435 fromList $ map f [0 .. (len - 1)]
436
437
438-- | zip for Vectors
439zipVector :: (Storable a, Storable b, Storable (a,b)) => Vector a -> Vector b -> Vector (a,b)
440zipVector = zipVectorWith (,)
441
442-- | unzip for Vectors
443unzipVector :: (Storable a, Storable b, Storable (a,b)) => Vector (a,b) -> (Vector a,Vector b)
444unzipVector = unzipVectorWith id
445
446-------------------------------------------------------------------
496 447