module Algebra.Matrix.IntMap (IMMatrix, MIMMatrix) where
import           Algebra.Matrix.Generic
import           Algebra.Matrix.Generic.Mutable (MMatrix)
import qualified Algebra.Matrix.Generic.Mutable as GM
import           Algebra.Prelude.Core
import           Control.DeepSeq
import           Data.IntMap                    (IntMap)
import qualified Data.IntMap                    as IM
import           Data.Vector                    (MVector, Vector)
import qualified Data.Vector                    as V
import           Data.Vector.Generic            (Mutable)
import qualified Data.Vector.Generic.Mutable    as MV (basicInitialize,
                                                       basicLength)
import qualified Data.Vector.Mutable            as MV

-- | Sparse matrix represented by a finite map from index to an element.
data IMMatrix a = IMM { IMMatrix a -> Vector (IntMap a)
imRows :: Vector (IntMap a)
                      , IMMatrix a -> Int
imColCount :: Int
                      }
                  deriving (IMMatrix a -> IMMatrix a -> Bool
(IMMatrix a -> IMMatrix a -> Bool)
-> (IMMatrix a -> IMMatrix a -> Bool) -> Eq (IMMatrix a)
forall a. Eq a => IMMatrix a -> IMMatrix a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: IMMatrix a -> IMMatrix a -> Bool
$c/= :: forall a. Eq a => IMMatrix a -> IMMatrix a -> Bool
== :: IMMatrix a -> IMMatrix a -> Bool
$c== :: forall a. Eq a => IMMatrix a -> IMMatrix a -> Bool
Eq, Eq (IMMatrix a)
Eq (IMMatrix a)
-> (IMMatrix a -> IMMatrix a -> Ordering)
-> (IMMatrix a -> IMMatrix a -> Bool)
-> (IMMatrix a -> IMMatrix a -> Bool)
-> (IMMatrix a -> IMMatrix a -> Bool)
-> (IMMatrix a -> IMMatrix a -> Bool)
-> (IMMatrix a -> IMMatrix a -> IMMatrix a)
-> (IMMatrix a -> IMMatrix a -> IMMatrix a)
-> Ord (IMMatrix a)
IMMatrix a -> IMMatrix a -> Bool
IMMatrix a -> IMMatrix a -> Ordering
IMMatrix a -> IMMatrix a -> IMMatrix a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (IMMatrix a)
forall a. Ord a => IMMatrix a -> IMMatrix a -> Bool
forall a. Ord a => IMMatrix a -> IMMatrix a -> Ordering
forall a. Ord a => IMMatrix a -> IMMatrix a -> IMMatrix a
min :: IMMatrix a -> IMMatrix a -> IMMatrix a
$cmin :: forall a. Ord a => IMMatrix a -> IMMatrix a -> IMMatrix a
max :: IMMatrix a -> IMMatrix a -> IMMatrix a
$cmax :: forall a. Ord a => IMMatrix a -> IMMatrix a -> IMMatrix a
>= :: IMMatrix a -> IMMatrix a -> Bool
$c>= :: forall a. Ord a => IMMatrix a -> IMMatrix a -> Bool
> :: IMMatrix a -> IMMatrix a -> Bool
$c> :: forall a. Ord a => IMMatrix a -> IMMatrix a -> Bool
<= :: IMMatrix a -> IMMatrix a -> Bool
$c<= :: forall a. Ord a => IMMatrix a -> IMMatrix a -> Bool
< :: IMMatrix a -> IMMatrix a -> Bool
$c< :: forall a. Ord a => IMMatrix a -> IMMatrix a -> Bool
compare :: IMMatrix a -> IMMatrix a -> Ordering
$ccompare :: forall a. Ord a => IMMatrix a -> IMMatrix a -> Ordering
$cp1Ord :: forall a. Ord a => Eq (IMMatrix a)
Ord)

instance NFData a => NFData (IMMatrix a) where
  rnf :: IMMatrix a -> ()
rnf (IMM Vector (IntMap a)
vs Int
i) = Vector (IntMap a) -> ()
forall a. NFData a => a -> ()
rnf Vector (IntMap a)
vs () -> () -> ()
`seq` Int -> ()
forall a. NFData a => a -> ()
rnf Int
i () -> () -> ()
`seq` ()

instance (DecidableZero a, Show a) => Show (IMMatrix a) where
  showsPrec :: Int -> IMMatrix a -> ShowS
showsPrec Int
d = Int -> [Vector a] -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
d ([Vector a] -> ShowS)
-> (IMMatrix a -> [Vector a]) -> IMMatrix a -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IMMatrix a -> [Vector a]
forall (mat :: * -> *) a. Matrix mat a => mat a -> [Row mat a]
toRows

lookCoe :: Monoidal c => IM.Key -> IntMap c -> c
lookCoe :: Int -> IntMap c -> c
lookCoe Int
a = c -> Maybe c -> c
forall a. a -> Maybe a -> a
fromMaybe c
forall m. Monoidal m => m
zero (Maybe c -> c) -> (IntMap c -> Maybe c) -> IntMap c -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> IntMap c -> Maybe c
forall a. Int -> IntMap a -> Maybe a
IM.lookup Int
a

-- | Mutable version of @'IMMatrix'@, but the same.
data MIMMatrix s a = MIM { MIMMatrix s a -> MVector s (IntMap a)
_mimRows :: MVector s (IntMap a)
                         , MIMMatrix s a -> Int
_mimColCount :: Int
                         }

guardZero :: DecidableZero a => a -> Maybe a
guardZero :: a -> Maybe a
guardZero a
a | a -> Bool
forall r. DecidableZero r => r -> Bool
isZero a
a = Maybe a
forall a. Maybe a
Nothing
            | Bool
otherwise = a -> Maybe a
forall a. a -> Maybe a
Just a
a
{-# INLINE guardZero #-}

cmpMatrixSizeMsg :: IMMatrix a1 -> IMMatrix a2 -> String
cmpMatrixSizeMsg :: IMMatrix a1 -> IMMatrix a2 -> String
cmpMatrixSizeMsg IMMatrix a1
m IMMatrix a2
m'
  = [String] -> String
unwords [ Int -> String
forall a. Show a => a -> String
show (Vector (IntMap a1) -> Int
forall a. Vector a -> Int
V.length (Vector (IntMap a1) -> Int) -> Vector (IntMap a1) -> Int
forall a b. (a -> b) -> a -> b
$ IMMatrix a1 -> Vector (IntMap a1)
forall a. IMMatrix a -> Vector (IntMap a)
imRows IMMatrix a1
m) String -> ShowS
forall w. Monoid w => w -> w -> w
++ String
"x" String -> ShowS
forall w. Monoid w => w -> w -> w
++ Int -> String
forall a. Show a => a -> String
show (IMMatrix a1 -> Int
forall a. IMMatrix a -> Int
imColCount IMMatrix a1
m)
            , String
"matrix with"
            , Int -> String
forall a. Show a => a -> String
show (Vector (IntMap a2) -> Int
forall a. Vector a -> Int
V.length (Vector (IntMap a2) -> Int) -> Vector (IntMap a2) -> Int
forall a b. (a -> b) -> a -> b
$ IMMatrix a2 -> Vector (IntMap a2)
forall a. IMMatrix a -> Vector (IntMap a)
imRows IMMatrix a2
m') String -> ShowS
forall w. Monoid w => w -> w -> w
++ String
"x" String -> ShowS
forall w. Monoid w => w -> w -> w
++ Int -> String
forall a. Show a => a -> String
show (IMMatrix a2 -> Int
forall a. IMMatrix a -> Int
imColCount IMMatrix a2
m')
            ]

instance DecidableZero a => Additive (IMMatrix a) where
  m :: IMMatrix a
m@(IMM Vector (IntMap a)
rs Int
cs) + :: IMMatrix a -> IMMatrix a -> IMMatrix a
+ m' :: IMMatrix a
m'@(IMM Vector (IntMap a)
rs' Int
cs')
    | Int
cs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
cs' Bool -> Bool -> Bool
&& Vector (IntMap a) -> Int
forall a. Vector a -> Int
V.length Vector (IntMap a)
rs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Vector (IntMap a) -> Int
forall a. Vector a -> Int
V.length Vector (IntMap a)
rs'
    = Vector (IntMap a) -> Int -> IMMatrix a
forall a. Vector (IntMap a) -> Int -> IMMatrix a
IMM ((IntMap a -> IntMap a -> IntMap a)
-> Vector (IntMap a) -> Vector (IntMap a) -> Vector (IntMap a)
forall a b c. (a -> b -> c) -> Vector a -> Vector b -> Vector c
V.zipWith ((a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
forall a. (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
IM.unionWith a -> a -> a
forall r. Additive r => r -> r -> r
(+)) Vector (IntMap a)
rs Vector (IntMap a)
rs') Int
cs
    | Bool
otherwise =
      String -> IMMatrix a
forall a. HasCallStack => String -> a
error (String -> IMMatrix a) -> String -> IMMatrix a
forall a b. (a -> b) -> a -> b
$
      [String] -> String
unwords [String
"(Additive.+):"
              , String
"adding"
              , IMMatrix a -> IMMatrix a -> String
forall a1 a2. IMMatrix a1 -> IMMatrix a2 -> String
cmpMatrixSizeMsg IMMatrix a
m IMMatrix a
m'
              ]

dot :: (DecidableZero a, Ring a) => IntMap a -> Vector a -> a
dot :: IntMap a -> Vector a -> a
dot IntMap a
row Vector a
col = IntMap a -> a
forall (f :: * -> *) m. (Foldable f, Monoidal m) => f m -> m
sum (IntMap a -> a) -> IntMap a -> a
forall a b. (a -> b) -> a -> b
$ (Int -> a -> Maybe a) -> IntMap a -> IntMap a
forall a b. (Int -> a -> Maybe b) -> IntMap a -> IntMap b
IM.mapMaybeWithKey (\Int
k a
a -> a -> Maybe a
forall a. DecidableZero a => a -> Maybe a
guardZero (a -> Maybe a) -> a -> Maybe a
forall a b. (a -> b) -> a -> b
$ a
a a -> a -> a
forall r. Multiplicative r => r -> r -> r
* (Vector a
col Vector a -> Int -> a
forall a. Vector a -> Int -> a
V.! Int
k)) IntMap a
row

instance (Ring a, DecidableZero a) => Multiplicative (IMMatrix a) where
  IMMatrix a
m * :: IMMatrix a -> IMMatrix a -> IMMatrix a
* IMMatrix a
m'
    | IMMatrix a -> Int
forall (mat :: * -> *) a. Matrix mat a => mat a -> Int
columnCount IMMatrix a
m Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= IMMatrix a -> Int
forall (mat :: * -> *) a. Matrix mat a => mat a -> Int
rowCount IMMatrix a
m' =
      String -> IMMatrix a
forall a. HasCallStack => String -> a
error (String -> IMMatrix a) -> String -> IMMatrix a
forall a b. (a -> b) -> a -> b
$ [String] -> String
unwords [ String
"(Multiplicative.*)", String
"multipling", IMMatrix a -> IMMatrix a -> String
forall a1 a2. IMMatrix a1 -> IMMatrix a2 -> String
cmpMatrixSizeMsg IMMatrix a
m IMMatrix a
m']
    | Bool
otherwise =
      let loop :: IntMap a -> IntMap a
loop IntMap a
row =
            [(Int, a)] -> IntMap a
forall a. [(Int, a)] -> IntMap a
IM.fromList [ (Int
j, IntMap a -> Vector a -> a
forall a. (DecidableZero a, Ring a) => IntMap a -> Vector a -> a
dot IntMap a
row (Vector a -> a) -> Vector a -> a
forall a b. (a -> b) -> a -> b
$ (IntMap a -> a) -> Vector (IntMap a) -> Vector a
forall a b. (a -> b) -> Vector a -> Vector b
V.map (Int -> IntMap a -> a
forall c. Monoidal c => Int -> IntMap c -> c
lookCoe Int
j) (Vector (IntMap a) -> Vector a) -> Vector (IntMap a) -> Vector a
forall a b. (a -> b) -> a -> b
$ IMMatrix a -> Vector (IntMap a)
forall a. IMMatrix a -> Vector (IntMap a)
imRows IMMatrix a
m')
                        | Int
j <- [Int
0.. IMMatrix a -> Int
forall a. IMMatrix a -> Int
imColCount IMMatrix a
m' Int -> Int -> Int
forall r. Group r => r -> r -> r
- Int
1]
                        ]
          rs :: Vector (IntMap a)
rs = (IntMap a -> IntMap a) -> Vector (IntMap a) -> Vector (IntMap a)
forall a b. (a -> b) -> Vector a -> Vector b
V.map IntMap a -> IntMap a
loop (IMMatrix a -> Vector (IntMap a)
forall a. IMMatrix a -> Vector (IntMap a)
imRows IMMatrix a
m)
      in Vector (IntMap a) -> Int -> IMMatrix a
forall a. Vector (IntMap a) -> Int -> IMMatrix a
IMM Vector (IntMap a)
rs (IMMatrix a -> Int
forall a. IMMatrix a -> Int
imColCount IMMatrix a
m')

type instance Mutable IMMatrix = MIMMatrix
type instance Row IMMatrix = Vector
type instance Column IMMatrix = Vector

instance DecidableZero a => Matrix IMMatrix a where
  basicRowCount :: IMMatrix a -> Int
basicRowCount (IMM Vector (IntMap a)
v Int
_) = Vector (IntMap a) -> Int
forall a. Vector a -> Int
V.length Vector (IntMap a)
v
  basicColumnCount :: IMMatrix a -> Int
basicColumnCount (IMM Vector (IntMap a)
_ Int
c) = Int
c
  unsafeFreeze :: Mutable IMMatrix (PrimState m) a -> m (IMMatrix a)
unsafeFreeze (MIM v c) = (Vector (IntMap a) -> Int -> IMMatrix a)
-> Int -> Vector (IntMap a) -> IMMatrix a
forall a b c. (a -> b -> c) -> b -> a -> c
flip Vector (IntMap a) -> Int -> IMMatrix a
forall a. Vector (IntMap a) -> Int -> IMMatrix a
IMM Int
c (Vector (IntMap a) -> IMMatrix a)
-> m (Vector (IntMap a)) -> m (IMMatrix a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MVector (PrimState m) (IntMap a) -> m (Vector (IntMap a))
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> m (Vector a)
V.unsafeFreeze MVector (PrimState m) (IntMap a)
v
  unsafeThaw :: IMMatrix a -> m (Mutable IMMatrix (PrimState m) a)
unsafeThaw   (IMM Vector (IntMap a)
v Int
c) = (MVector (PrimState m) (IntMap a)
 -> Int -> MIMMatrix (PrimState m) a)
-> Int
-> MVector (PrimState m) (IntMap a)
-> MIMMatrix (PrimState m) a
forall a b c. (a -> b -> c) -> b -> a -> c
flip MVector (PrimState m) (IntMap a)
-> Int -> MIMMatrix (PrimState m) a
forall s a. MVector s (IntMap a) -> Int -> MIMMatrix s a
MIM Int
c (MVector (PrimState m) (IntMap a) -> MIMMatrix (PrimState m) a)
-> m (MVector (PrimState m) (IntMap a))
-> m (MIMMatrix (PrimState m) a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vector (IntMap a) -> m (MVector (PrimState m) (IntMap a))
forall (m :: * -> *) a.
PrimMonad m =>
Vector a -> m (MVector (PrimState m) a)
V.unsafeThaw Vector (IntMap a)
v
  basicUnsafeIndexM :: IMMatrix a -> Int -> Int -> m a
basicUnsafeIndexM (IMM Vector (IntMap a)
v Int
_) Int
i Int
j = a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> m a) -> a -> m a
forall a b. (a -> b) -> a -> b
$ a -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybe a
forall m. Monoidal m => m
zero (Maybe a -> a) -> Maybe a -> a
forall a b. (a -> b) -> a -> b
$ Int -> IntMap a -> Maybe a
forall a. Int -> IntMap a -> Maybe a
IM.lookup Int
j (IntMap a -> Maybe a) -> IntMap a -> Maybe a
forall a b. (a -> b) -> a -> b
$ Vector (IntMap a) -> Int -> IntMap a
forall a. Vector a -> Int -> a
V.unsafeIndex Vector (IntMap a)
v Int
i
  basicUnsafeGetRowM :: IMMatrix a -> Int -> m (Row IMMatrix a)
basicUnsafeGetRowM (IMM Vector (IntMap a)
v Int
c) Int
i = Vector a -> m (Vector a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Vector a -> m (Vector a)) -> Vector a -> m (Vector a)
forall a b. (a -> b) -> a -> b
$ Int -> (Int -> a) -> Vector a
forall a. Int -> (Int -> a) -> Vector a
V.generate Int
c ((Int -> a) -> Vector a) -> (Int -> a) -> Vector a
forall a b. (a -> b) -> a -> b
$ \Int
j ->
    a -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybe a
forall m. Monoidal m => m
zero (Maybe a -> a) -> Maybe a -> a
forall a b. (a -> b) -> a -> b
$ Int -> IntMap a -> Maybe a
forall a. Int -> IntMap a -> Maybe a
IM.lookup Int
j (IntMap a -> Maybe a) -> IntMap a -> Maybe a
forall a b. (a -> b) -> a -> b
$ Vector (IntMap a)
v Vector (IntMap a) -> Int -> IntMap a
forall a. Vector a -> Int -> a
V.! Int
i
  basicUnsafeGetColumnM :: IMMatrix a -> Int -> m (Column IMMatrix a)
basicUnsafeGetColumnM (IMM Vector (IntMap a)
v Int
_) Int
j = Vector a -> m (Vector a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Vector a -> m (Vector a)) -> Vector a -> m (Vector a)
forall a b. (a -> b) -> a -> b
$ (IntMap a -> a) -> Vector (IntMap a) -> Vector a
forall a b. (a -> b) -> Vector a -> Vector b
V.map (a -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybe a
forall m. Monoidal m => m
zero (Maybe a -> a) -> (IntMap a -> Maybe a) -> IntMap a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> IntMap a -> Maybe a
forall a. Int -> IntMap a -> Maybe a
IM.lookup Int
j) Vector (IntMap a)
v

mfromIM :: Monoidal a => Size -> IntMap a -> Vector a
mfromIM :: Int -> IntMap a -> Vector a
mfromIM Int
n IntMap a
dic = Int -> (Int -> a) -> Vector a
forall a. Int -> (Int -> a) -> Vector a
V.generate Int
n ((Int -> a) -> Vector a) -> (Int -> a) -> Vector a
forall a b. (a -> b) -> a -> b
$ \Int
k -> a -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybe a
forall m. Monoidal m => m
zero (Maybe a -> a) -> Maybe a -> a
forall a b. (a -> b) -> a -> b
$ Int -> IntMap a -> Maybe a
forall a. Int -> IntMap a -> Maybe a
IM.lookup Int
k IntMap a
dic

mrowToIM :: (DecidableZero a) => Vector a -> IntMap a
mrowToIM :: Vector a -> IntMap a
mrowToIM Vector a
mv =
  [(Int, a)] -> IntMap a
forall a. [(Int, a)] -> IntMap a
IM.fromList ([(Int, a)] -> IntMap a) -> [(Int, a)] -> IntMap a
forall a b. (a -> b) -> a -> b
$ Vector (Int, a) -> [(Int, a)]
forall a. Vector a -> [a]
V.toList (Vector (Int, a) -> [(Int, a)]) -> Vector (Int, a) -> [(Int, a)]
forall a b. (a -> b) -> a -> b
$
  (Int -> a -> Maybe (Int, a)) -> Vector a -> Vector (Int, a)
forall a b. (Int -> a -> Maybe b) -> Vector a -> Vector b
V.imapMaybe (\Int
i a
k -> if a -> Bool
forall r. DecidableZero r => r -> Bool
isZero a
k then Maybe (Int, a)
forall a. Maybe a
Nothing else (Int, a) -> Maybe (Int, a)
forall a. a -> Maybe a
Just (Int
i, a
k)) Vector a
mv

type instance Row    MIMMatrix = Vector
type instance Column MIMMatrix = Vector
instance DecidableZero a => MMatrix MIMMatrix a where
  basicUnsafeNew :: Int -> Int -> m (MIMMatrix (PrimState m) a)
basicUnsafeNew Int
n Int
m = (MVector (PrimState m) (IntMap a)
 -> Int -> MIMMatrix (PrimState m) a)
-> Int
-> MVector (PrimState m) (IntMap a)
-> MIMMatrix (PrimState m) a
forall a b c. (a -> b -> c) -> b -> a -> c
flip MVector (PrimState m) (IntMap a)
-> Int -> MIMMatrix (PrimState m) a
forall s a. MVector s (IntMap a) -> Int -> MIMMatrix s a
MIM Int
m (MVector (PrimState m) (IntMap a) -> MIMMatrix (PrimState m) a)
-> m (MVector (PrimState m) (IntMap a))
-> m (MIMMatrix (PrimState m) a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> m (MVector (PrimState m) (IntMap a))
forall (m :: * -> *) a.
PrimMonad m =>
Int -> m (MVector (PrimState m) a)
MV.unsafeNew Int
n
  basicInitialise :: MIMMatrix (PrimState m) a -> m ()
basicInitialise (MIM MVector (PrimState m) (IntMap a)
v Int
_) = MVector (PrimState m) (IntMap a) -> m ()
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
v (PrimState m) a -> m ()
MV.basicInitialize MVector (PrimState m) (IntMap a)
v m () -> m () -> m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> MVector (PrimState m) (IntMap a) -> IntMap a -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> a -> m ()
MV.set MVector (PrimState m) (IntMap a)
v IntMap a
forall a. IntMap a
IM.empty
  basicRowCount :: MIMMatrix s a -> Int
basicRowCount (MIM MVector s (IntMap a)
v Int
_) = MVector s (IntMap a) -> Int
forall (v :: * -> * -> *) a s. MVector v a => v s a -> Int
MV.basicLength MVector s (IntMap a)
v
  basicColumnCount :: MIMMatrix s a -> Int
basicColumnCount (MIM MVector s (IntMap a)
_ Int
w) = Int
w
  unsafeGetRow :: Int -> MIMMatrix (PrimState m) a -> m (Row MIMMatrix a)
unsafeGetRow Int
i (MIM MVector (PrimState m) (IntMap a)
v Int
c) = Int -> IntMap a -> Vector a
forall a. Monoidal a => Int -> IntMap a -> Vector a
mfromIM Int
c (IntMap a -> Vector a) -> m (IntMap a) -> m (Vector a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MVector (PrimState m) (IntMap a) -> Int -> m (IntMap a)
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> m a
MV.read MVector (PrimState m) (IntMap a)
v Int
i
  unsafeGetColumn :: Int -> MIMMatrix (PrimState m) a -> m (Column MIMMatrix a)
unsafeGetColumn Int
i (MIM MVector (PrimState m) (IntMap a)
v Int
_) =
    (IntMap a -> a) -> Vector (IntMap a) -> Vector a
forall a b. (a -> b) -> Vector a -> Vector b
V.map (a -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybe a
forall m. Monoidal m => m
zero (Maybe a -> a) -> (IntMap a -> Maybe a) -> IntMap a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> IntMap a -> Maybe a
forall a. Int -> IntMap a -> Maybe a
IM.lookup Int
i) (Vector (IntMap a) -> Vector a)
-> m (Vector (IntMap a)) -> m (Vector a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MVector (PrimState m) (IntMap a) -> m (Vector (IntMap a))
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> m (Vector a)
V.unsafeFreeze MVector (PrimState m) (IntMap a)
v
  unsafeFromRows :: [Row MIMMatrix a] -> m (MIMMatrix (PrimState m) a)
unsafeFromRows [Row MIMMatrix a]
rs =
    (MVector (PrimState m) (IntMap a)
 -> Int -> MIMMatrix (PrimState m) a)
-> Int
-> MVector (PrimState m) (IntMap a)
-> MIMMatrix (PrimState m) a
forall a b c. (a -> b -> c) -> b -> a -> c
flip MVector (PrimState m) (IntMap a)
-> Int -> MIMMatrix (PrimState m) a
forall s a. MVector s (IntMap a) -> Int -> MIMMatrix s a
MIM (Vector a -> Int
forall a. Vector a -> Int
V.length (Vector a -> Int) -> Vector a -> Int
forall a b. (a -> b) -> a -> b
$ [Vector a] -> Vector a
forall a. [a] -> a
head [Vector a]
[Row MIMMatrix a]
rs) (MVector (PrimState m) (IntMap a) -> MIMMatrix (PrimState m) a)
-> m (MVector (PrimState m) (IntMap a))
-> m (MIMMatrix (PrimState m) a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vector (IntMap a) -> m (MVector (PrimState m) (IntMap a))
forall (m :: * -> *) a.
PrimMonad m =>
Vector a -> m (MVector (PrimState m) a)
V.unsafeThaw ([IntMap a] -> Vector (IntMap a)
forall a. [a] -> Vector a
V.fromList ([IntMap a] -> Vector (IntMap a))
-> [IntMap a] -> Vector (IntMap a)
forall a b. (a -> b) -> a -> b
$ (Vector a -> IntMap a) -> [Vector a] -> [IntMap a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map Vector a -> IntMap a
forall a. DecidableZero a => Vector a -> IntMap a
mrowToIM [Vector a]
[Row MIMMatrix a]
rs)
  unsafeCopy :: MIMMatrix (PrimState m) a -> MIMMatrix (PrimState m) a -> m ()
unsafeCopy (MIM MVector (PrimState m) (IntMap a)
v Int
_) (MIM MVector (PrimState m) (IntMap a)
u Int
_) = MVector (PrimState m) (IntMap a)
-> MVector (PrimState m) (IntMap a) -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> MVector (PrimState m) a -> m ()
MV.unsafeCopy MVector (PrimState m) (IntMap a)
v MVector (PrimState m) (IntMap a)
u
  unsafeRead :: MIMMatrix (PrimState m) a -> Int -> Int -> m a
unsafeRead (MIM MVector (PrimState m) (IntMap a)
v Int
_) Int
r Int
c =
    a -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybe a
forall m. Monoidal m => m
zero (Maybe a -> a) -> (IntMap a -> Maybe a) -> IntMap a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> IntMap a -> Maybe a
forall a. Int -> IntMap a -> Maybe a
IM.lookup Int
c (IntMap a -> a) -> m (IntMap a) -> m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MVector (PrimState m) (IntMap a) -> Int -> m (IntMap a)
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> m a
MV.unsafeRead MVector (PrimState m) (IntMap a)
v Int
r
  unsafeWrite :: MIMMatrix (PrimState m) a -> Int -> Int -> a -> m ()
unsafeWrite (MIM MVector (PrimState m) (IntMap a)
v Int
_) Int
r Int
c a
x
    | a -> Bool
forall r. DecidableZero r => r -> Bool
isZero a
x  = () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    | Bool
otherwise = MVector (PrimState m) (IntMap a) -> Int -> IntMap a -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> a -> m ()
MV.write MVector (PrimState m) (IntMap a)
v Int
r (IntMap a -> m ()) -> (IntMap a -> IntMap a) -> IntMap a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a -> IntMap a -> IntMap a
forall a. Int -> a -> IntMap a -> IntMap a
IM.insert Int
c a
x (IntMap a -> m ()) -> m (IntMap a) -> m ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< MVector (PrimState m) (IntMap a) -> Int -> m (IntMap a)
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> m a
MV.read MVector (PrimState m) (IntMap a)
v Int
r
  basicUnsafeSwapRows :: MIMMatrix (PrimState m) a -> Int -> Int -> m ()
basicUnsafeSwapRows (MIM MVector (PrimState m) (IntMap a)
v Int
_) = MVector (PrimState m) (IntMap a) -> Int -> Int -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> Int -> m ()
MV.swap MVector (PrimState m) (IntMap a)
v
  basicSet :: MIMMatrix (PrimState m) a -> a -> m ()
basicSet (MIM MVector (PrimState m) (IntMap a)
v Int
c) a
a = MVector (PrimState m) (IntMap a) -> IntMap a -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> a -> m ()
MV.set MVector (PrimState m) (IntMap a)
v (IntMap a -> m ()) -> IntMap a -> m ()
forall a b. (a -> b) -> a -> b
$ [(Int, a)] -> IntMap a
forall a. [(Int, a)] -> IntMap a
IM.fromList [(Int
i, a
a) | Int
i <- [Int
0.. Int
c Int -> Int -> Int
forall r. Group r => r -> r -> r
- Int
1]]
  unsafeScaleRow :: MIMMatrix (PrimState m) a -> Int -> a -> m ()
unsafeScaleRow (MIM MVector (PrimState m) (IntMap a)
v Int
_) Int
i a
c =
    MVector (PrimState m) (IntMap a) -> Int -> IntMap a -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> a -> m ()
MV.write MVector (PrimState m) (IntMap a)
v Int
i (IntMap a -> m ()) -> (IntMap a -> IntMap a) -> IntMap a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Maybe a) -> IntMap a -> IntMap a
forall a b. (a -> Maybe b) -> IntMap a -> IntMap b
IM.mapMaybe (a -> Maybe a
forall a. DecidableZero a => a -> Maybe a
guardZero (a -> Maybe a) -> (a -> a) -> a -> Maybe a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a
c a -> a -> a
forall r. Multiplicative r => r -> r -> r
*))
    (IntMap a -> m ()) -> m (IntMap a) -> m ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< MVector (PrimState m) (IntMap a) -> Int -> m (IntMap a)
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> m a
MV.read MVector (PrimState m) (IntMap a)
v Int
i
  basicUnsafeIMapRowM :: MIMMatrix (PrimState m) a -> Int -> (Int -> a -> m a) -> m ()
basicUnsafeIMapRowM (MIM MVector (PrimState m) (IntMap a)
v Int
c) Int
i Int -> a -> m a
f =
    [Int] -> (Int -> m ()) -> m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
0..Int
c Int -> Int -> Int
forall r. Group r => r -> r -> r
- Int
1] ((Int -> m ()) -> m ()) -> (Int -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \Int
j -> do
    IntMap a
dic <- MVector (PrimState m) (IntMap a) -> Int -> m (IntMap a)
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> m a
MV.read MVector (PrimState m) (IntMap a)
v Int
i
    a
a <- Int -> a -> m a
f Int
j (a -> m a) -> a -> m a
forall a b. (a -> b) -> a -> b
$ a -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybe a
forall m. Monoidal m => m
zero (Maybe a -> a) -> Maybe a -> a
forall a b. (a -> b) -> a -> b
$ Int -> IntMap a -> Maybe a
forall a. Int -> IntMap a -> Maybe a
IM.lookup Int
j IntMap a
dic
    if a -> Bool
forall r. DecidableZero r => r -> Bool
isZero a
a
      then MVector (PrimState m) (IntMap a) -> Int -> IntMap a -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> a -> m ()
MV.write MVector (PrimState m) (IntMap a)
v Int
i (IntMap a -> m ()) -> IntMap a -> m ()
forall a b. (a -> b) -> a -> b
$ Int -> IntMap a -> IntMap a
forall a. Int -> IntMap a -> IntMap a
IM.delete Int
j IntMap a
dic
      else MVector (PrimState m) (IntMap a) -> Int -> IntMap a -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> a -> m ()
MV.write MVector (PrimState m) (IntMap a)
v Int
i (IntMap a -> m ()) -> IntMap a -> m ()
forall a b. (a -> b) -> a -> b
$ Int -> a -> IntMap a -> IntMap a
forall a. Int -> a -> IntMap a -> IntMap a
IM.insert Int
j a
a IntMap a
dic