easytensor-0.2.0.0: src/Numeric/DataFrame/IO.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UnboxedTuples #-}
-----------------------------------------------------------------------------
-- |
-- Module : Numeric.DataFrame.IO
-- Copyright : (c) Artem Chirkin
-- License : BSD3
--
-- Maintainer : chirkin@arch.ethz.ch
--
-- Mutable DataFrames living in IO.
--
-----------------------------------------------------------------------------
module Numeric.DataFrame.IO
( MutableFrame (), IODataFrame ()
, newDataFrame, copyDataFrame, copyMutableDataFrame
, unsafeFreezeDataFrame
, freezeDataFrame, thawDataFrame
, writeDataFrame, readDataFrame
, writeDataFrameOff, readDataFrameOff
) where
import GHC.Prim (RealWorld)
import GHC.Types (Int (..), IO (..))
import Numeric.Commons
import Numeric.DataFrame.Type
import Numeric.DataFrame.Mutable
import Numeric.Dimensions
import Numeric.Scalar
-- | Mutable DataFrame that lives in IO.
-- Internal representation is always a ByteArray.
newtype IODataFrame t (ns :: [Nat]) = IODataFrame (MDataFrame RealWorld t (ns :: [Nat]))
-- | Create a new mutable DataFrame.
newDataFrame :: forall t (ns :: [Nat])
. ( PrimBytes t, Dimensions ns)
=> IO (IODataFrame t ns)
newDataFrame = IODataFrame <$> IO (newDataFrame# @t @ns)
{-# INLINE newDataFrame #-}
-- | Copy one DataFrame into another mutable DataFrame at specified position.
copyDataFrame :: forall t (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat])
. ( PrimBytes (DataFrame t as)
, ConcatList as bs asbs
, Dimensions bs
)
=> DataFrame t as -> Idx bs -> IODataFrame t asbs -> IO ()
copyDataFrame df ei (IODataFrame mdf) = IO (copyDataFrame# df ei mdf)
{-# INLINE copyDataFrame #-}
-- | Copy one mutable DataFrame into another mutable DataFrame at specified position.
copyMutableDataFrame :: forall t (as :: [Nat]) (bs :: [Nat]) (asbs :: [Nat])
. ( PrimBytes t
, ConcatList as bs asbs
, Dimensions bs
)
=> IODataFrame t as -> Idx bs -> IODataFrame t asbs -> IO ()
copyMutableDataFrame (IODataFrame mdfA) ei (IODataFrame mdfB)
= IO (copyMDataFrame# mdfA ei mdfB)
{-# INLINE copyMutableDataFrame #-}
-- | Make a mutable DataFrame immutable, without copying.
unsafeFreezeDataFrame :: forall t (ns :: [Nat])
. PrimBytes (DataFrame t ns)
=> IODataFrame t ns -> IO (DataFrame t ns)
unsafeFreezeDataFrame (IODataFrame mdf) = IO (unsafeFreezeDataFrame# mdf)
{-# INLINE unsafeFreezeDataFrame #-}
-- | Copy content of a mutable DataFrame into a new immutable DataFrame.
freezeDataFrame :: forall t (ns :: [Nat])
. PrimBytes (DataFrame t ns)
=> IODataFrame t ns -> IO (DataFrame t ns)
freezeDataFrame (IODataFrame mdf) = IO (freezeDataFrame# mdf)
{-# INLINE freezeDataFrame #-}
-- | Create a new mutable DataFrame and copy content of immutable one in there.
thawDataFrame :: forall t (ns :: [Nat])
. PrimBytes (DataFrame t ns)
=> DataFrame t ns -> IO (IODataFrame t ns)
thawDataFrame df = IODataFrame <$> IO (thawDataFrame# df)
{-# INLINE thawDataFrame #-}
-- | Write a single element at the specified index
writeDataFrame :: forall t (ns :: [Nat])
. ( MutableFrame t ns, Dimensions ns )
=> IODataFrame t ns -> Idx ns -> Scalar t -> IO ()
writeDataFrame (IODataFrame mdf) ei = IO . writeDataFrame# mdf ei . unScalar
{-# INLINE writeDataFrame #-}
-- | Read a single element at the specified index
readDataFrame :: forall t (ns :: [Nat])
. ( MutableFrame t ns, Dimensions ns )
=> IODataFrame t ns -> Idx ns -> IO (Scalar t)
readDataFrame (IODataFrame mdf) = fmap scalar . IO . readDataFrame# mdf
{-# INLINE readDataFrame #-}
-- | Write a single element at the specified element offset
writeDataFrameOff :: forall t (ns :: [Nat])
. ( MutableFrame t ns, Dimensions ns )
=> IODataFrame t ns -> Int -> Scalar t -> IO ()
writeDataFrameOff (IODataFrame mdf) (I# i) x = IO $ \s -> (# writeDataFrameOff# mdf i (unScalar x) s, () #)
{-# INLINE writeDataFrameOff #-}
-- | Read a single element at the specified element offset
readDataFrameOff :: forall t (ns :: [Nat])
. ( MutableFrame t ns, Dimensions ns )
=> IODataFrame t ns -> Int -> IO (Scalar t)
readDataFrameOff (IODataFrame mdf) (I# i) = scalar <$> IO (readDataFrameOff# mdf i)
{-# INLINE readDataFrameOff #-}