matrix-sized-0.1.0: src/Data/Matrix/Static/Dense/Mutable.hs
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE StrictData #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Data.Matrix.Static.Dense.Mutable
( -- * Mutable Matrix
MMatrix(..)
, C.dim
, C.unsafeWrite
, C.unsafeRead
, C.new
, C.replicate
) where
import qualified Data.Vector.Generic.Mutable as GM
import Prelude hiding (read, replicate)
import Data.Singletons
import Control.Monad.Primitive (PrimMonad, PrimState)
import qualified Data.Matrix.Static.Generic.Mutable as C
-- | Column-major mutable matrix.
data MMatrix :: C.MMatrixKind where
MMatrix :: (SingI r, SingI c) => v s a -> MMatrix r c v s a
instance GM.MVector v a => C.MMatrix MMatrix v a where
dim :: forall r c s. MMatrix r c v s a -> (Int, Int)
dim (MMatrix _) = (r,c)
where
r = fromIntegral $ fromSing (sing :: Sing r)
c = fromIntegral $ fromSing (sing :: Sing c)
{-# INLINE dim #-}
unsafeRead mat@(MMatrix v) (i,j) = GM.unsafeRead v idx
where
(r, _) = C.dim mat
idx = i + j * r
{-# INLINE unsafeRead #-}
unsafeWrite mat@(MMatrix v) (i,j) = GM.unsafeWrite v idx
where
(r, _) = C.dim mat
idx = i + j * r
{-# INLINE unsafeWrite #-}
unsafeModify mat@(MMatrix v) f (i,j) = GM.unsafeModify v f idx
where
(r, _) = C.dim mat
idx = i + j * r
{-# INLINE unsafeModify #-}
fill (MMatrix v) x = GM.set v x
{-# INLINE fill #-}
new :: forall r c s. (SingI r, SingI c, PrimMonad s)
=> s (MMatrix r c v (PrimState s) a)
new = MMatrix <$> GM.new (r*c)
where
r = fromIntegral $ fromSing (sing :: Sing r)
c = fromIntegral $ fromSing (sing :: Sing c)
{-# INLINE new #-}
replicate :: forall r c s. (SingI r, SingI c, PrimMonad s)
=> a -> s (MMatrix r c v (PrimState s) a)
replicate x = MMatrix <$> GM.replicate (r*c) x
where
r = fromIntegral $ fromSing (sing :: Sing r)
c = fromIntegral $ fromSing (sing :: Sing c)
{-# INLINE replicate #-}
{-
takeColumn :: GM.MVector v a => MMatrix v m a -> Int -> v m a
takeColumn (MMatrix _ c tda offset vec) i = GM.slice i' c vec
where
i' = offset + i * tda
{-# INLINE takeColumn #-}
-}