module Data.Packed.Internal.Vector where
import Data.Packed.Internal.Common
import Foreign
import Complex
import Control.Monad(when)
data Vector t = V { dim :: Int
, fptr :: ForeignPtr t
}
vec = withVector
withVector (V n fp) f = withForeignPtr fp $ \p -> do
let v g = do
g (fi n) p
f v
createVector :: Storable a => Int -> IO (Vector a)
createVector n = do
when (n <= 0) $ error ("trying to createVector of dim "++show n)
fp <- mallocForeignPtrArray n
return $ V n fp
fromList :: Storable a => [a] -> Vector a
fromList l = unsafePerformIO $ do
v <- createVector (length l)
let f _ p = pokeArray p l >> return 0
app1 f vec v "fromList"
return v
safeRead v = unsafePerformIO . withForeignPtr (fptr v)
toList :: Storable a => Vector a -> [a]
toList v = safeRead v $ peekArray (dim v)
(|>) :: (Storable a) => Int -> [a] -> Vector a
infixl 9 |>
n |> l = if length l == n then fromList l else error "|> with wrong size"
at' :: Storable a => Vector a -> Int -> a
at' v n = safeRead v $ flip peekElemOff n
at :: Storable a => Vector a -> Int -> a
at v n | n >= 0 && n < dim v = at' v n
| otherwise = error "vector index out of range"
subVector :: Storable t => Int
-> Int
-> Vector t
-> Vector t
subVector k l (v@V {dim=n})
| k<0 || k >= n || k+l > n || l < 0 = error "subVector out of range"
| otherwise = unsafePerformIO $ do
r <- createVector l
let f _ s _ d = copyArray d (advancePtr s k) l >> return 0
app2 f vec v vec r "subVector"
return r
(@>) :: Storable t => Vector t -> Int -> t
infixl 9 @>
(@>) = at
join :: Storable t => [Vector t] -> Vector t
join [] = error "joining zero vectors"
join as = unsafePerformIO $ do
let tot = sum (map dim as)
r@V {fptr = p} <- createVector tot
withForeignPtr p $ \ptr ->
joiner as tot ptr
return r
where joiner [] _ _ = return ()
joiner (V {dim = n, fptr = b} : cs) _ p = do
withForeignPtr b $ \pb -> copyArray p pb n
joiner cs 0 (advancePtr p n)
asReal :: Vector (Complex Double) -> Vector Double
asReal v = V { dim = 2*dim v, fptr = castForeignPtr (fptr v) }
asComplex :: Vector Double -> Vector (Complex Double)
asComplex v = V { dim = dim v `div` 2, fptr = castForeignPtr (fptr v) }
liftVector :: (Storable a, Storable b) => (a-> b) -> Vector a -> Vector b
liftVector f = fromList . map f . toList
liftVector2 :: (Storable a, Storable b, Storable c) => (a-> b -> c) -> Vector a -> Vector b -> Vector c
liftVector2 f u v = fromList $ zipWith f (toList u) (toList v)