diff options
author | Alberto Ruiz <aruiz@um.es> | 2015-06-05 16:53:45 +0200 |
---|---|---|
committer | Alberto Ruiz <aruiz@um.es> | 2015-06-05 16:53:45 +0200 |
commit | a5d14b70e70a93b2dec29fc0dfa7940488dc264a (patch) | |
tree | 2e1d698ca261a1ec492a2b47680a9de9723b482c /packages/base | |
parent | ba04d65298266a2f6a37061bedaca4ea3cf7fae6 (diff) |
move internal vector
Diffstat (limited to 'packages/base')
-rw-r--r-- | packages/base/src/Data/Packed/Vector.hs | 125 | ||||
-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 | |||
18 | module 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 | |||
29 | import Data.Packed.Internal.Vector | ||
30 | import Foreign.Storable | ||
31 | |||
32 | ------------------------------------------------------------------- | ||
33 | |||
34 | #ifdef BINARY | ||
35 | |||
36 | import Data.Binary | ||
37 | import Control.Monad(replicateM) | ||
38 | |||
39 | import Data.ByteString.Internal as BS | ||
40 | import Foreign.ForeignPtr(castForeignPtr) | ||
41 | import Data.Vector.Storable.Internal(updPtr) | ||
42 | import Foreign.Ptr(plusPtr) | ||
43 | |||
44 | |||
45 | -- a 64K cache, with a Double taking 13 bytes in Bytestring, | ||
46 | -- implies a chunk size of 5041 | ||
47 | chunk :: Int | ||
48 | chunk = 5000 | ||
49 | |||
50 | chunks :: Int -> [Int] | ||
51 | chunks 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 | |||
55 | putVector v = mapM_ put $! toList v | ||
56 | |||
57 | getVector d = do | ||
58 | xs <- replicateM d get | ||
59 | return $! fromList xs | ||
60 | |||
61 | -------------------------------------------------------------------------------- | ||
62 | |||
63 | toByteString :: Storable t => Vector t -> ByteString | ||
64 | toByteString 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 | |||
70 | fromByteString :: Storable t => ByteString -> Vector t | ||
71 | fromByteString (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 | |||
79 | instance (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 | ||
104 | 4 |> [0.0,1.0,2.0,3.0]@ | ||
105 | |||
106 | -} | ||
107 | buildVector :: Storable a => Int -> (Int -> a) -> Vector a | ||
108 | buildVector len f = | ||
109 | fromList $ map f [0 .. (len - 1)] | ||
110 | |||
111 | |||
112 | -- | zip for Vectors | ||
113 | zipVector :: (Storable a, Storable b, Storable (a,b)) => Vector a -> Vector b -> Vector (a,b) | ||
114 | zipVector = zipVectorWith (,) | ||
115 | |||
116 | -- | unzip for Vectors | ||
117 | unzipVector :: (Storable a, Storable b, Storable (a,b)) => Vector (a,b) -> (Vector a,Vector b) | ||
118 | unzipVector = unzipVectorWith id | ||
119 | |||
120 | ------------------------------------------------------------------- | ||
121 | |||
122 | {-# DEPRECATED join "use vjoin or Data.Vector.concat" #-} | ||
123 | join :: Storable t => [Vector t] -> Vector t | ||
124 | join = 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 | ||
13 | module Data.Packed.Internal.Vector ( | 13 | module Internal.Vector where |
14 | Vector, dim, | 14 | |
15 | fromList, toList, (|>), | 15 | import Internal.Tools |
16 | vjoin, (@>), safe, at, at', subVector, takesV, | 16 | import Foreign.Marshal.Array ( peekArray, copyArray, advancePtr ) |
17 | mapVector, mapVectorWithIndex, zipVectorWith, unzipVectorWith, | 17 | import Foreign.ForeignPtr ( ForeignPtr, castForeignPtr ) |
18 | mapVectorM, mapVectorM_, mapVectorWithIndexM, mapVectorWithIndexM_, | 18 | import Foreign.Ptr ( Ptr ) |
19 | foldVector, foldVectorG, foldLoop, foldVectorWithIndex, | 19 | import Foreign.Storable |
20 | createVector, vec, | 20 | ( Storable, peekElemOff, pokeElemOff, sizeOf ) |
21 | asComplex, asReal, float2DoubleV, double2FloatV, double2IntV, int2DoubleV, float2IntV, int2floatV, | 21 | import Foreign.C.Types ( CInt ) |
22 | stepF, stepD, stepI, condF, condD, condI, | 22 | import Data.Complex ( Complex ) |
23 | conjugateQ, conjugateC, | 23 | import System.IO.Unsafe ( unsafePerformIO ) |
24 | cloneVector, | 24 | import GHC.ForeignPtr ( mallocPlainForeignPtrBytes ) |
25 | unsafeToForeignPtr, | 25 | import GHC.Base ( realWorld#, IO(IO), when ) |
26 | unsafeFromForeignPtr, | 26 | import qualified Data.Vector.Storable as Vector |
27 | unsafeWith, | 27 | ( Vector, slice, length ) |
28 | CInt, I | 28 | import Data.Vector.Storable |
29 | ) where | 29 | ( fromList, unsafeToForeignPtr, unsafeFromForeignPtr, unsafeWith ) |
30 | 30 | ||
31 | import Data.Packed.Internal.Common | 31 | |
32 | import Data.Packed.Internal.Signatures | 32 | #ifdef BINARY |
33 | import Foreign.Marshal.Array(peekArray, copyArray, advancePtr) | 33 | |
34 | import Foreign.ForeignPtr(ForeignPtr, castForeignPtr) | 34 | import Data.Binary |
35 | import Foreign.Ptr(Ptr) | 35 | import Control.Monad(replicateM) |
36 | import Foreign.Storable(Storable, peekElemOff, pokeElemOff, sizeOf) | 36 | import qualified Data.ByteString.Internal as BS |
37 | import Foreign.C.Types | 37 | import Data.Vector.Storable.Internal(updPtr) |
38 | import Data.Complex | 38 | import Foreign.Ptr(plusPtr) |
39 | import System.IO.Unsafe(unsafePerformIO) | ||
40 | |||
41 | #if __GLASGOW_HASKELL__ >= 605 | ||
42 | import GHC.ForeignPtr (mallocPlainForeignPtrBytes) | ||
43 | #else | ||
44 | import Foreign.ForeignPtr (mallocForeignPtrBytes) | ||
45 | #endif | ||
46 | 39 | ||
47 | import GHC.Base | ||
48 | #if __GLASGOW_HASKELL__ < 612 | ||
49 | import GHC.IOBase hiding (liftIO) | ||
50 | #endif | 40 | #endif |
51 | 41 | ||
52 | import qualified Data.Vector.Storable as Vector | ||
53 | import Data.Vector.Storable(Vector, | ||
54 | fromList, | ||
55 | unsafeToForeignPtr, | ||
56 | unsafeFromForeignPtr, | ||
57 | unsafeWith) | ||
58 | 42 | ||
59 | type I = CInt | 43 | |
44 | type Vector = Vector.Vector | ||
60 | 45 | ||
61 | -- | Number of elements | 46 | -- | Number of elements |
62 | dim :: (Storable t) => Vector t -> Int | 47 | dim :: (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] | |||
116 | toList v = safeRead v $ peekArray (dim v) | 97 | toList 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 |
127 | infixl 9 |> | 108 | infixl 9 |> |
128 | n |> l = if length l' == n | 109 | n |> 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 | ||
135 | at' :: Storable a => Vector a -> Int -> a | ||
136 | at' 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) | ||
144 | safe :: Bool | ||
145 | safe = False | ||
146 | #else | ||
147 | safe = True | ||
148 | #endif | ||
149 | 115 | ||
150 | -- | access to Vector elements with range checking. | 116 | -- | Create a vector of indexes, useful for matrix extraction using '??' |
151 | at :: Storable a => Vector a -> Int -> a | 117 | idxs :: [Int] -> Vector I |
152 | at v n | 118 | idxs 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 | |||
169 | subVector = Vector.slice | 130 | subVector = 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 |
179 | infixl 9 @> | 142 | infixl 9 @> |
180 | (@>) = at | 143 | v @> 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 | ||
149 | at' :: Storable a => Vector a -> Int -> a | ||
150 | at' 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) | |||
227 | asComplex v = unsafeFromForeignPtr (castForeignPtr fp) (i `div` 2) (n `div` 2) | 197 | asComplex 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 | |||
232 | float2DoubleV :: Vector Float -> Vector Double | ||
233 | float2DoubleV = tog c_float2double | ||
234 | |||
235 | double2FloatV :: Vector Double -> Vector Float | ||
236 | double2FloatV = tog c_double2float | ||
237 | |||
238 | double2IntV :: Vector Double -> Vector CInt | ||
239 | double2IntV = tog c_double2int | ||
240 | |||
241 | int2DoubleV :: Vector CInt -> Vector Double | ||
242 | int2DoubleV = tog c_int2double | ||
243 | |||
244 | float2IntV :: Vector Float -> Vector CInt | ||
245 | float2IntV = tog c_float2int | ||
246 | |||
247 | int2floatV :: Vector CInt -> Vector Float | ||
248 | int2floatV = tog c_int2float | ||
249 | |||
250 | |||
251 | tog f v = unsafePerformIO $ do | ||
252 | r <- createVector (dim v) | ||
253 | app2 f vec v vec r "tog" | ||
254 | return r | ||
255 | |||
256 | foreign import ccall unsafe "float2double" c_float2double :: TFV | ||
257 | foreign import ccall unsafe "double2float" c_double2float :: TVF | ||
258 | foreign import ccall unsafe "int2double" c_int2double :: CV CInt (CV Double (IO CInt)) | ||
259 | foreign import ccall unsafe "double2int" c_double2int :: CV Double (CV CInt (IO CInt)) | ||
260 | foreign import ccall unsafe "int2float" c_int2float :: CV CInt (CV Float (IO CInt)) | ||
261 | foreign import ccall unsafe "float2int" c_float2int :: CV Float (CV CInt (IO CInt)) | ||
262 | |||
263 | |||
264 | --------------------------------------------------------------- | ||
265 | |||
266 | step f v = unsafePerformIO $ do | ||
267 | r <- createVector (dim v) | ||
268 | app2 f vec v vec r "step" | ||
269 | return r | ||
270 | |||
271 | stepD :: Vector Double -> Vector Double | ||
272 | stepD = step c_stepD | ||
273 | |||
274 | stepF :: Vector Float -> Vector Float | ||
275 | stepF = step c_stepF | ||
276 | |||
277 | stepI :: Vector CInt -> Vector CInt | ||
278 | stepI = step c_stepI | ||
279 | |||
280 | foreign import ccall unsafe "stepF" c_stepF :: TFF | ||
281 | foreign import ccall unsafe "stepD" c_stepD :: TVV | ||
282 | foreign import ccall unsafe "stepI" c_stepI :: CV CInt (CV CInt (IO CInt)) | ||
283 | |||
284 | --------------------------------------------------------------- | ||
285 | |||
286 | condF :: Vector Float -> Vector Float -> Vector Float -> Vector Float -> Vector Float -> Vector Float | ||
287 | condF = condg c_condF | ||
288 | |||
289 | condD :: Vector Double -> Vector Double -> Vector Double -> Vector Double -> Vector Double -> Vector Double | ||
290 | condD = condg c_condD | ||
291 | |||
292 | condI :: Vector CInt -> Vector CInt -> Vector CInt -> Vector CInt -> Vector CInt -> Vector CInt | ||
293 | condI = condg c_condI | ||
294 | |||
295 | |||
296 | condg 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 | |||
302 | foreign import ccall unsafe "condF" c_condF :: CInt -> PF -> CInt -> PF -> CInt -> PF -> TFFF | ||
303 | foreign import ccall unsafe "condD" c_condD :: CInt -> PD -> CInt -> PD -> CInt -> PD -> TVVV | ||
304 | foreign 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 | ||
308 | conjugateAux fun x = unsafePerformIO $ do | ||
309 | v <- createVector (dim x) | ||
310 | app2 fun vec x vec v "conjugateAux" | ||
311 | return v | ||
312 | |||
313 | conjugateQ :: Vector (Complex Float) -> Vector (Complex Float) | ||
314 | conjugateQ = conjugateAux c_conjugateQ | ||
315 | foreign import ccall unsafe "conjugateQ" c_conjugateQ :: TQVQV | ||
316 | |||
317 | conjugateC :: Vector (Complex Double) -> Vector (Complex Double) | ||
318 | conjugateC = conjugateAux c_conjugateC | ||
319 | foreign import ccall unsafe "conjugateC" c_conjugateC :: TCVCV | ||
320 | |||
321 | -------------------------------------------------------------------------------- | ||
322 | |||
323 | cloneVector :: Storable t => Vector t -> IO (Vector t) | ||
324 | cloneVector 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 |
334 | mapVector :: (Storable a, Storable b) => (a-> b) -> Vector a -> Vector b | 204 | mapVector :: (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 | ||
408 | foldVectorG f s0 v = foldLoop g s0 (dim v) | 278 | foldVectorG 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 | ||
373 | chunk :: Int | ||
374 | chunk = 5000 | ||
375 | |||
376 | chunks :: Int -> [Int] | ||
377 | chunks 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 | |||
381 | putVector v = mapM_ put $! toList v | ||
382 | |||
383 | getVector d = do | ||
384 | xs <- replicateM d get | ||
385 | return $! fromList xs | ||
386 | |||
387 | -------------------------------------------------------------------------------- | ||
388 | |||
389 | toByteString :: Storable t => Vector t -> BS.ByteString | ||
390 | toByteString 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 | |||
396 | fromByteString :: Storable t => BS.ByteString -> Vector t | ||
397 | fromByteString (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 | |||
405 | instance (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 | ||
430 | 4 |> [0.0,1.0,2.0,3.0]@ | ||
431 | |||
432 | -} | ||
433 | buildVector :: Storable a => Int -> (Int -> a) -> Vector a | ||
434 | buildVector len f = | ||
435 | fromList $ map f [0 .. (len - 1)] | ||
436 | |||
437 | |||
438 | -- | zip for Vectors | ||
439 | zipVector :: (Storable a, Storable b, Storable (a,b)) => Vector a -> Vector b -> Vector (a,b) | ||
440 | zipVector = zipVectorWith (,) | ||
441 | |||
442 | -- | unzip for Vectors | ||
443 | unzipVector :: (Storable a, Storable b, Storable (a,b)) => Vector (a,b) -> (Vector a,Vector b) | ||
444 | unzipVector = unzipVectorWith id | ||
445 | |||
446 | ------------------------------------------------------------------- | ||
496 | 447 | ||