diff options
author | Alberto Ruiz <aruiz@um.es> | 2010-03-01 11:15:22 +0000 |
---|---|---|
committer | Alberto Ruiz <aruiz@um.es> | 2010-03-01 11:15:22 +0000 |
commit | 283f3033f86fabde2290bb28a59e7d87fd0754f5 (patch) | |
tree | ac9000c976a805636b557b916af9e139922df70c /lib/Data/Packed/Internal | |
parent | 54bcc1fc1e0f9676cb10f627f412eeeea34b5d2c (diff) |
compatible with vector
Diffstat (limited to 'lib/Data/Packed/Internal')
-rw-r--r-- | lib/Data/Packed/Internal/Matrix.hs | 24 | ||||
-rw-r--r-- | lib/Data/Packed/Internal/Vector.hs | 75 |
2 files changed, 55 insertions, 44 deletions
diff --git a/lib/Data/Packed/Internal/Matrix.hs b/lib/Data/Packed/Internal/Matrix.hs index a6b6215..b8e7ab0 100644 --- a/lib/Data/Packed/Internal/Matrix.hs +++ b/lib/Data/Packed/Internal/Matrix.hs | |||
@@ -18,7 +18,7 @@ | |||
18 | module Data.Packed.Internal.Matrix( | 18 | module Data.Packed.Internal.Matrix( |
19 | Matrix(..), rows, cols, | 19 | Matrix(..), rows, cols, |
20 | MatrixOrder(..), orderOf, | 20 | MatrixOrder(..), orderOf, |
21 | createMatrix, withMatrix, mat, | 21 | createMatrix, mat, |
22 | cmat, fmat, | 22 | cmat, fmat, |
23 | toLists, flatten, reshape, | 23 | toLists, flatten, reshape, |
24 | Element(..), | 24 | Element(..), |
@@ -115,11 +115,11 @@ fmat m@MF{} = m | |||
115 | fmat MC {irows = r, icols = c, cdat = d } = MF {irows = r, icols = c, fdat = transdata c d r} | 115 | fmat MC {irows = r, icols = c, cdat = d } = MF {irows = r, icols = c, fdat = transdata c d r} |
116 | 116 | ||
117 | -- C-Haskell matrix adapter | 117 | -- C-Haskell matrix adapter |
118 | mat :: Adapt (CInt -> CInt -> Ptr t -> r) (Matrix t) r | 118 | -- mat :: Adapt (CInt -> CInt -> Ptr t -> r) (Matrix t) r |
119 | mat = withMatrix | ||
120 | 119 | ||
121 | withMatrix a f = | 120 | mat :: (Storable t) => Matrix t -> (((CInt -> CInt -> Ptr t -> t1) -> t1) -> IO b) -> IO b |
122 | withForeignPtr (fptr (xdat a)) $ \p -> do | 121 | mat a f = |
122 | unsafeWith (xdat a) $ \p -> do | ||
123 | let m g = do | 123 | let m g = do |
124 | g (fi (rows a)) (fi (cols a)) p | 124 | g (fi (rows a)) (fi (cols a)) p |
125 | f m | 125 | f m |
@@ -273,8 +273,8 @@ transdata' c1 v c2 = | |||
273 | then v | 273 | then v |
274 | else unsafePerformIO $ do | 274 | else unsafePerformIO $ do |
275 | w <- createVector (r2*c2) | 275 | w <- createVector (r2*c2) |
276 | withForeignPtr (fptr v) $ \p -> | 276 | unsafeWith v $ \p -> |
277 | withForeignPtr (fptr w) $ \q -> do | 277 | unsafeWith w $ \q -> do |
278 | let go (-1) _ = return () | 278 | let go (-1) _ = return () |
279 | go !i (-1) = go (i-1) (c1-1) | 279 | go !i (-1) = go (i-1) (c1-1) |
280 | go !i !j = do x <- peekElemOff p (i*c1+j) | 280 | go !i !j = do x <- peekElemOff p (i*c1+j) |
@@ -300,8 +300,8 @@ transdataAux fun c1 d c2 = | |||
300 | then d | 300 | then d |
301 | else unsafePerformIO $ do | 301 | else unsafePerformIO $ do |
302 | v <- createVector (dim d) | 302 | v <- createVector (dim d) |
303 | withForeignPtr (fptr d) $ \pd -> | 303 | unsafeWith d $ \pd -> |
304 | withForeignPtr (fptr v) $ \pv -> | 304 | unsafeWith v $ \pv -> |
305 | fun (fi r1) (fi c1) pd (fi r2) (fi c2) pv // check "transdataAux" | 305 | fun (fi r1) (fi c1) pd (fi r2) (fi c2) pv // check "transdataAux" |
306 | return v | 306 | return v |
307 | where r1 = dim d `div` c1 | 307 | where r1 = dim d `div` c1 |
@@ -314,7 +314,7 @@ foreign import ccall "transC" ctransC :: TCMCM | |||
314 | 314 | ||
315 | constant' v n = unsafePerformIO $ do | 315 | constant' v n = unsafePerformIO $ do |
316 | w <- createVector n | 316 | w <- createVector n |
317 | withForeignPtr (fptr w) $ \p -> do | 317 | unsafeWith w $ \p -> do |
318 | let go (-1) = return () | 318 | let go (-1) = return () |
319 | go !k = pokeElemOff p k v >> go (k-1) | 319 | go !k = pokeElemOff p k v >> go (k-1) |
320 | go (n-1) | 320 | go (n-1) |
@@ -352,8 +352,8 @@ subMatrix (r0,c0) (rt,ct) m | |||
352 | 352 | ||
353 | subMatrix'' (r0,c0) (rt,ct) c v = unsafePerformIO $ do | 353 | subMatrix'' (r0,c0) (rt,ct) c v = unsafePerformIO $ do |
354 | w <- createVector (rt*ct) | 354 | w <- createVector (rt*ct) |
355 | withForeignPtr (fptr v) $ \p -> | 355 | unsafeWith v $ \p -> |
356 | withForeignPtr (fptr w) $ \q -> do | 356 | unsafeWith w $ \q -> do |
357 | let go (-1) _ = return () | 357 | let go (-1) _ = return () |
358 | go !i (-1) = go (i-1) (ct-1) | 358 | go !i (-1) = go (i-1) (ct-1) |
359 | go !i !j = do x <- peekElemOff p ((i+r0)*c+j+c0) | 359 | go !i !j = do x <- peekElemOff p ((i+r0)*c+j+c0) |
diff --git a/lib/Data/Packed/Internal/Vector.hs b/lib/Data/Packed/Internal/Vector.hs index 51c0d92..6bbd207 100644 --- a/lib/Data/Packed/Internal/Vector.hs +++ b/lib/Data/Packed/Internal/Vector.hs | |||
@@ -12,20 +12,20 @@ | |||
12 | -- Vector implementation | 12 | -- Vector implementation |
13 | -- | 13 | -- |
14 | ----------------------------------------------------------------------------- | 14 | ----------------------------------------------------------------------------- |
15 | -- #hide | ||
16 | 15 | ||
17 | module Data.Packed.Internal.Vector ( | 16 | module Data.Packed.Internal.Vector ( |
18 | Vector(..), dim, | 17 | Vector, dim, |
19 | fromList, toList, (|>), | 18 | fromList, toList, (|>), |
20 | join, (@>), safe, at, at', subVector, | 19 | join, (@>), safe, at, at', subVector, |
21 | mapVector, zipVector, | 20 | mapVector, zipVector, |
22 | foldVector, foldVectorG, foldLoop, | 21 | foldVector, foldVectorG, foldLoop, |
23 | createVector, withVector, vec, | 22 | createVector, vec, |
24 | asComplex, asReal, | 23 | asComplex, asReal, |
25 | fwriteVector, freadVector, fprintfVector, fscanfVector, | 24 | fwriteVector, freadVector, fprintfVector, fscanfVector, |
26 | cloneVector, | 25 | cloneVector, |
27 | unsafeToForeignPtr, | 26 | unsafeToForeignPtr, |
28 | unsafeFromForeignPtr | 27 | unsafeFromForeignPtr, |
28 | unsafeWith | ||
29 | ) where | 29 | ) where |
30 | 30 | ||
31 | import Data.Packed.Internal.Common | 31 | import Data.Packed.Internal.Common |
@@ -47,39 +47,45 @@ import GHC.Base | |||
47 | import GHC.IOBase | 47 | import GHC.IOBase |
48 | #endif | 48 | #endif |
49 | 49 | ||
50 | -- | A one-dimensional array of objects stored in a contiguous memory block. | 50 | -- | One-dimensional array of objects stored in a contiguous memory block. |
51 | data Vector t = | 51 | data Vector t = |
52 | V { idim :: {-# UNPACK #-} !Int -- ^ number of elements | 52 | V { ioff :: {-# UNPACK #-} !Int -- ^ offset of first element |
53 | , fptr :: {-# UNPACK #-} !(ForeignPtr t) -- ^ foreign pointer to the memory block | 53 | , idim :: {-# UNPACK #-} !Int -- ^ number of elements |
54 | , fptr :: {-# UNPACK #-} !(ForeignPtr t) -- ^ foreign pointer to the memory block | ||
54 | } | 55 | } |
55 | 56 | ||
56 | unsafeToForeignPtr :: Vector a -> (ForeignPtr a, Int, Int) | 57 | unsafeToForeignPtr :: Vector a -> (ForeignPtr a, Int, Int) |
57 | unsafeToForeignPtr v = (fptr v, 0, idim v) | 58 | unsafeToForeignPtr v = (fptr v, ioff v, idim v) |
58 | 59 | ||
59 | -- | Same convention as in Roman Leshchinskiy's vector package. | 60 | -- | Same convention as in Roman Leshchinskiy's vector package. |
60 | unsafeFromForeignPtr :: ForeignPtr a -> Int -> Int -> Vector a | 61 | unsafeFromForeignPtr :: ForeignPtr a -> Int -> Int -> Vector a |
61 | unsafeFromForeignPtr fp i n | i == 0 = V {idim = n, fptr = fp} | 62 | unsafeFromForeignPtr fp i n | n > 0 = V {ioff = i, idim = n, fptr = fp} |
62 | | otherwise = error "unsafeFromForeignPtr with nonzero offset" | 63 | | otherwise = error "unsafeFromForeignPtr with dim < 1" |
64 | |||
65 | unsafeWith (V i _ fp) m = withForeignPtr fp $ \p -> m (p `advancePtr` i) | ||
66 | {-# INLINE unsafeWith #-} | ||
67 | |||
63 | 68 | ||
64 | -- | Number of elements | 69 | -- | Number of elements |
65 | dim :: Vector t -> Int | 70 | dim :: Vector t -> Int |
66 | dim = idim | 71 | dim = idim |
67 | 72 | ||
68 | -- C-Haskell vector adapter | 73 | -- C-Haskell vector adapter |
69 | vec :: Adapt (CInt -> Ptr t -> r) (Vector t) r | 74 | -- vec :: Adapt (CInt -> Ptr t -> r) (Vector t) r |
70 | vec = withVector | 75 | vec :: (Storable t) => Vector t -> (((CInt -> Ptr t -> t1) -> t1) -> IO b) -> IO b |
71 | 76 | vec x f = unsafeWith x $ \p -> do | |
72 | withVector (V n fp) f = withForeignPtr fp $ \p -> do | ||
73 | let v g = do | 77 | let v g = do |
74 | g (fi n) p | 78 | g (fi $ dim x) p |
75 | f v | 79 | f v |
80 | {-# INLINE vec #-} | ||
81 | |||
76 | 82 | ||
77 | -- allocates memory for a new vector | 83 | -- allocates memory for a new vector |
78 | createVector :: Storable a => Int -> IO (Vector a) | 84 | createVector :: Storable a => Int -> IO (Vector a) |
79 | createVector n = do | 85 | createVector n = do |
80 | when (n <= 0) $ error ("trying to createVector of dim "++show n) | 86 | when (n <= 0) $ error ("trying to createVector of dim "++show n) |
81 | fp <- doMalloc undefined | 87 | fp <- doMalloc undefined |
82 | return $ V n fp | 88 | return $ V 0 n fp |
83 | where | 89 | where |
84 | -- | 90 | -- |
85 | -- Use the much cheaper Haskell heap allocated storage | 91 | -- Use the much cheaper Haskell heap allocated storage |
@@ -102,11 +108,10 @@ createVector n = do | |||
102 | fromList :: Storable a => [a] -> Vector a | 108 | fromList :: Storable a => [a] -> Vector a |
103 | fromList l = unsafePerformIO $ do | 109 | fromList l = unsafePerformIO $ do |
104 | v <- createVector (length l) | 110 | v <- createVector (length l) |
105 | let f _ p = pokeArray p l >> return 0 | 111 | unsafeWith v $ \ p -> pokeArray p l |
106 | app1 f vec v "fromList" | ||
107 | return v | 112 | return v |
108 | 113 | ||
109 | safeRead v = inlinePerformIO . withForeignPtr (fptr v) | 114 | safeRead v = inlinePerformIO . unsafeWith v |
110 | {-# INLINE safeRead #-} | 115 | {-# INLINE safeRead #-} |
111 | 116 | ||
112 | inlinePerformIO :: IO a -> a | 117 | inlinePerformIO :: IO a -> a |
@@ -171,7 +176,12 @@ subVector :: Storable t => Int -- ^ index of the starting element | |||
171 | -> Int -- ^ number of elements to extract | 176 | -> Int -- ^ number of elements to extract |
172 | -> Vector t -- ^ source | 177 | -> Vector t -- ^ source |
173 | -> Vector t -- ^ result | 178 | -> Vector t -- ^ result |
174 | subVector k l (v@V {idim=n}) | 179 | |
180 | subVector k l v@V{idim = n, ioff = i} | ||
181 | | k<0 || k >= n || k+l > n || l < 0 = error "subVector out of range" | ||
182 | | otherwise = v {idim = l, ioff = i+k} | ||
183 | |||
184 | subVectorCopy k l (v@V {idim=n}) | ||
175 | | k<0 || k >= n || k+l > n || l < 0 = error "subVector out of range" | 185 | | k<0 || k >= n || k+l > n || l < 0 = error "subVector out of range" |
176 | | otherwise = unsafePerformIO $ do | 186 | | otherwise = unsafePerformIO $ do |
177 | r <- createVector l | 187 | r <- createVector l |
@@ -201,23 +211,24 @@ join [] = error "joining zero vectors" | |||
201 | join [v] = v | 211 | join [v] = v |
202 | join as = unsafePerformIO $ do | 212 | join as = unsafePerformIO $ do |
203 | let tot = sum (map dim as) | 213 | let tot = sum (map dim as) |
204 | r@V {fptr = p} <- createVector tot | 214 | r <- createVector tot |
205 | withForeignPtr p $ \ptr -> | 215 | unsafeWith r $ \ptr -> |
206 | joiner as tot ptr | 216 | joiner as tot ptr |
207 | return r | 217 | return r |
208 | where joiner [] _ _ = return () | 218 | where joiner [] _ _ = return () |
209 | joiner (V {idim = n, fptr = b} : cs) _ p = do | 219 | joiner (v:cs) _ p = do |
210 | withForeignPtr b $ \pb -> copyArray p pb n | 220 | let n = dim v |
221 | unsafeWith v $ \pb -> copyArray p pb n | ||
211 | joiner cs 0 (advancePtr p n) | 222 | joiner cs 0 (advancePtr p n) |
212 | 223 | ||
213 | 224 | ||
214 | -- | transforms a complex vector into a real vector with alternating real and imaginary parts | 225 | -- | transforms a complex vector into a real vector with alternating real and imaginary parts |
215 | asReal :: Vector (Complex Double) -> Vector Double | 226 | asReal :: Vector (Complex Double) -> Vector Double |
216 | asReal v = V { idim = 2*dim v, fptr = castForeignPtr (fptr v) } | 227 | asReal v = V { ioff = 2*ioff v, idim = 2*dim v, fptr = castForeignPtr (fptr v) } |
217 | 228 | ||
218 | -- | transforms a real vector into a complex vector with alternating real and imaginary parts | 229 | -- | transforms a real vector into a complex vector with alternating real and imaginary parts |
219 | asComplex :: Vector Double -> Vector (Complex Double) | 230 | asComplex :: Vector Double -> Vector (Complex Double) |
220 | asComplex v = V { idim = dim v `div` 2, fptr = castForeignPtr (fptr v) } | 231 | asComplex v = V { ioff = ioff v `div` 2, idim = dim v `div` 2, fptr = castForeignPtr (fptr v) } |
221 | 232 | ||
222 | ---------------------------------------------------------------- | 233 | ---------------------------------------------------------------- |
223 | 234 | ||
@@ -234,8 +245,8 @@ cloneVector (v@V {idim=n}) = do | |||
234 | mapVector :: (Storable a, Storable b) => (a-> b) -> Vector a -> Vector b | 245 | mapVector :: (Storable a, Storable b) => (a-> b) -> Vector a -> Vector b |
235 | mapVector f v = unsafePerformIO $ do | 246 | mapVector f v = unsafePerformIO $ do |
236 | w <- createVector (dim v) | 247 | w <- createVector (dim v) |
237 | withForeignPtr (fptr v) $ \p -> | 248 | unsafeWith v $ \p -> |
238 | withForeignPtr (fptr w) $ \q -> do | 249 | unsafeWith w $ \q -> do |
239 | let go (-1) = return () | 250 | let go (-1) = return () |
240 | go !k = do x <- peekElemOff p k | 251 | go !k = do x <- peekElemOff p k |
241 | pokeElemOff q k (f x) | 252 | pokeElemOff q k (f x) |
@@ -249,9 +260,9 @@ zipVector :: (Storable a, Storable b, Storable c) => (a-> b -> c) -> Vector a -> | |||
249 | zipVector f u v = unsafePerformIO $ do | 260 | zipVector f u v = unsafePerformIO $ do |
250 | let n = min (dim u) (dim v) | 261 | let n = min (dim u) (dim v) |
251 | w <- createVector n | 262 | w <- createVector n |
252 | withForeignPtr (fptr u) $ \pu -> | 263 | unsafeWith u $ \pu -> |
253 | withForeignPtr (fptr v) $ \pv -> | 264 | unsafeWith v $ \pv -> |
254 | withForeignPtr (fptr w) $ \pw -> do | 265 | unsafeWith w $ \pw -> do |
255 | let go (-1) = return () | 266 | let go (-1) = return () |
256 | go !k = do x <- peekElemOff pu k | 267 | go !k = do x <- peekElemOff pu k |
257 | y <- peekElemOff pv k | 268 | y <- peekElemOff pv k |
@@ -262,7 +273,7 @@ zipVector f u v = unsafePerformIO $ do | |||
262 | {-# INLINE zipVector #-} | 273 | {-# INLINE zipVector #-} |
263 | 274 | ||
264 | foldVector f x v = unsafePerformIO $ | 275 | foldVector f x v = unsafePerformIO $ |
265 | withForeignPtr (fptr (v::Vector Double)) $ \p -> do | 276 | unsafeWith (v::Vector Double) $ \p -> do |
266 | let go (-1) s = return s | 277 | let go (-1) s = return s |
267 | go !k !s = do y <- peekElemOff p k | 278 | go !k !s = do y <- peekElemOff p k |
268 | go (k-1::Int) (f y s) | 279 | go (k-1::Int) (f y s) |