{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -Wno-orphans -funbox-strict-fields #-}
-- | Provides @'Matrix'@ and @'MMatrix'@ instances for
--   @'DM.Matrix'@ type of @matrix@ package.
--
-- | __N.B.__ This module provides @0@-origin interface for @'DM.Matrix'@,
--            contrary to the @matrix@ package provides @1@-origin.
module Algebra.Matrix.DataMatrix (DMatrix) where
import           Algebra.Matrix.Generic
import           Algebra.Prelude.Core
import qualified Data.Coerce            as DC
import qualified Data.Matrix            as DM
import qualified Data.Vector            as V

type WIMatrix = WrapImmutable DM.Matrix
type DMatrix = DM.Matrix

type instance Mutable DM.Matrix = WIMatrix
type instance Row DM.Matrix = V.Vector
type instance Column DM.Matrix = V.Vector

instance (UnitNormalForm a, Ring a) => Matrix DM.Matrix a where
  basicRowCount :: Matrix a -> Size
basicRowCount = Matrix a -> Size
forall a. Matrix a -> Size
DM.nrows
  basicColumnCount :: Matrix a -> Size
basicColumnCount = Matrix a -> Size
forall a. Matrix a -> Size
DM.ncols
  basicUnsafeIndexM :: Matrix a -> Size -> Size -> m a
basicUnsafeIndexM Matrix a
m Size
i Size
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
$ Size -> Size -> Matrix a -> a
forall a. Size -> Size -> Matrix a -> a
DM.unsafeGet (Size
iSize -> Size -> Size
forall r. Additive r => r -> r -> r
+Size
1) (Size
jSize -> Size -> Size
forall r. Additive r => r -> r -> r
+Size
1) Matrix a
m
  basicUnsafeGetRowM :: Matrix a -> Size -> m (Row Matrix a)
basicUnsafeGetRowM Matrix a
m Size
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
$ Size -> Matrix a -> Vector a
forall a. Size -> Matrix a -> Vector a
DM.getRow (Size
i Size -> Size -> Size
forall r. Additive r => r -> r -> r
+ Size
1) Matrix a
m
  basicUnsafeGetColumnM :: Matrix a -> Size -> m (Column Matrix a)
basicUnsafeGetColumnM Matrix a
m Size
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
$ Size -> Matrix a -> Vector a
forall a. Size -> Matrix a -> Vector a
DM.getCol (Size
i Size -> Size -> Size
forall r. Additive r => r -> r -> r
+ Size
1) Matrix a
m
  unsafeGenerate :: Size -> Size -> (Size -> Size -> a) -> Matrix a
unsafeGenerate Size
w Size
h Size -> Size -> a
f = Size -> Size -> ((Size, Size) -> a) -> Matrix a
forall a. Size -> Size -> ((Size, Size) -> a) -> Matrix a
DM.matrix Size
w Size
h (((Size, Size) -> a) -> Matrix a)
-> ((Size, Size) -> a) -> Matrix a
forall a b. (a -> b) -> a -> b
$ \(Size
i, Size
j) -> Size -> Size -> a
f (Size
iSize -> Size -> Size
forall r. Group r => r -> r -> r
-Size
1) (Size
jSize -> Size -> Size
forall r. Group r => r -> r -> r
-Size
1)
  unsafeWrite :: Matrix a -> Size -> Size -> a -> Matrix a
unsafeWrite Matrix a
mat Size
i Size
j a
x = a -> (Size, Size) -> Matrix a -> Matrix a
forall a. a -> (Size, Size) -> Matrix a -> Matrix a
DM.unsafeSet a
x (Size
iSize -> Size -> Size
forall r. Additive r => r -> r -> r
+Size
1, Size
jSize -> Size -> Size
forall r. Additive r => r -> r -> r
+Size
1) Matrix a
mat
  unsafeFromRows :: [Row Matrix a] -> Matrix a
unsafeFromRows = (Matrix a -> Matrix a -> Matrix a) -> [Matrix a] -> Matrix a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 Matrix a -> Matrix a -> Matrix a
forall a. Matrix a -> Matrix a -> Matrix a
(DM.<->) ([Matrix a] -> Matrix a)
-> ([Vector a] -> [Matrix a]) -> [Vector a] -> Matrix a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Vector a -> Matrix a) -> [Vector a] -> [Matrix a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map Vector a -> Matrix a
forall a. Vector a -> Matrix a
DM.rowVector
  unsafeFromColumns :: [Column Matrix a] -> Matrix a
unsafeFromColumns = (Matrix a -> Matrix a -> Matrix a) -> [Matrix a] -> Matrix a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 Matrix a -> Matrix a -> Matrix a
forall a. Matrix a -> Matrix a -> Matrix a
(DM.<|>) ([Matrix a] -> Matrix a)
-> ([Vector a] -> [Matrix a]) -> [Vector a] -> Matrix a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Vector a -> Matrix a) -> [Vector a] -> [Matrix a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map Vector a -> Matrix a
forall a. Vector a -> Matrix a
DM.colVector

  toRows :: Matrix a -> [Row Matrix a]
toRows Matrix a
m = (Size -> Vector a) -> [Size] -> [Vector a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map (Size -> Matrix a -> Vector a
forall a. Size -> Matrix a -> Vector a
`DM.getRow` Matrix a
m) [Size
1..Matrix a -> Size
forall a. Matrix a -> Size
DM.nrows Matrix a
m]
  toColumns :: Matrix a -> [Column Matrix a]
toColumns Matrix a
m = (Size -> Vector a) -> [Size] -> [Vector a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map (Size -> Matrix a -> Vector a
forall a. Size -> Matrix a -> Vector a
`DM.getCol` Matrix a
m) [Size
1..Matrix a -> Size
forall a. Matrix a -> Size
DM.ncols Matrix a
m]

  swapRows :: Matrix a -> Size -> Size -> Matrix a
swapRows Matrix a
m Size
i Size
j = Size -> Size -> Matrix a -> Matrix a
forall a. Size -> Size -> Matrix a -> Matrix a
DM.switchRows (Size
iSize -> Size -> Size
forall r. Additive r => r -> r -> r
+Size
1) (Size
jSize -> Size -> Size
forall r. Additive r => r -> r -> r
+Size
1) Matrix a
m
  scaleRow :: Matrix a -> Size -> a -> Matrix a
scaleRow Matrix a
m Size
i a
c = Matrix (WrapAlgebra a) -> Matrix a
DC.coerce (Matrix (WrapAlgebra a) -> Matrix a)
-> Matrix (WrapAlgebra a) -> Matrix a
forall a b. (a -> b) -> a -> b
$ WrapAlgebra a
-> Size -> Matrix (WrapAlgebra a) -> Matrix (WrapAlgebra a)
forall a. Num a => a -> Size -> Matrix a -> Matrix a
DM.scaleRow (a -> WrapAlgebra a
forall a. a -> WrapAlgebra a
WrapAlgebra a
c) (Size
iSize -> Size -> Size
forall r. Additive r => r -> r -> r
+Size
1) (Matrix a -> Matrix (WrapAlgebra a)
DC.coerce Matrix a
m :: DM.Matrix (WrapAlgebra a))
  unsafeIMapRow :: Matrix a -> Size -> (Size -> a -> a) -> Matrix a
unsafeIMapRow Matrix a
m Size
i Size -> a -> a
f = (Size -> a -> a) -> Size -> Matrix a -> Matrix a
forall a. (Size -> a -> a) -> Size -> Matrix a -> Matrix a
DM.mapRow (\Size
k -> Size -> a -> a
f (Size
k Size -> Size -> Size
forall r. Group r => r -> r -> r
- Size
1)) (Size
iSize -> Size -> Size
forall r. Additive r => r -> r -> r
+Size
1) Matrix a
m
  combineRows :: Size -> a -> Size -> Matrix a -> Matrix a
combineRows Size
i a
c Size
j = (Matrix (WrapAlgebra a) -> Matrix (WrapAlgebra a))
-> Matrix a -> Matrix a
DC.coerce ((Matrix (WrapAlgebra a) -> Matrix (WrapAlgebra a))
 -> Matrix a -> Matrix a)
-> (Matrix (WrapAlgebra a) -> Matrix (WrapAlgebra a))
-> Matrix a
-> Matrix a
forall a b. (a -> b) -> a -> b
$ Size
-> WrapAlgebra a
-> Size
-> Matrix (WrapAlgebra a)
-> Matrix (WrapAlgebra a)
forall a. Num a => Size -> a -> Size -> Matrix a -> Matrix a
DM.combineRows (Size
iSize -> Size -> Size
forall r. Additive r => r -> r -> r
+Size
1) (a -> WrapAlgebra a
forall a. a -> WrapAlgebra a
WrapAlgebra a
c) (Size
jSize -> Size -> Size
forall r. Additive r => r -> r -> r
+Size
1)