module Feldspar.Matrix where
import qualified Prelude as P
import Feldspar.Prelude
import Feldspar.Utils
import Feldspar.Core
import Feldspar.Vector
type Matrix a = Vector (Vector (Data a))
freezeMatrix :: Storable a => Matrix a -> Data [[a]]
freezeMatrix = freezeVector . map freezeVector
unfreezeMatrix :: Storable a => Data Length -> Data Length -> Data [[a]] -> Matrix a
unfreezeMatrix y x = map (unfreezeVector x) . (unfreezeVector y)
matrix :: Storable a => [[a]] -> Matrix a
matrix as
| allEqual xs = unfreezeMatrix y x (value as)
| otherwise = error "matrix: Not rectangular"
where
xs = P.map P.length as
y = value $ P.length as
x = value $ P.head (xs P.++ [0])
indexedMat ::
Data Int -> Data Int -> (Data Int -> Data Int -> Data a) -> Matrix a
indexedMat m n idx = indexed m $ \k -> indexed n $ \l -> idx k l
transpose :: Matrix a -> Matrix a
transpose a = indexedMat (length $ head a) (length a) $ \y x -> a ! x ! y
flatten :: Matrix a -> Vector (Data a)
flatten matr = Indexed (m*n) ixf
where
m = length matr
n = (m==0) ? (0, length (head matr))
ixf i = matr ! y ! x
where
y = i `div` n
x = i `mod` n
diagonal :: Matrix a -> Vector (Data a)
diagonal m = zipWith (!) m (0 ... (length m 1))
distributeL :: (a -> b -> c) -> a -> Vector b -> Vector c
distributeL f = map . f
distributeR :: (a -> b -> c) -> Vector a -> b -> Vector c
distributeR = flip . distributeL . flip
class Mul a b
where
type Prod a b
(**) :: a -> b -> Prod a b
instance Numeric a => Mul (Data a) (Data a)
where
type Prod (Data a) (Data a) = Data a
(**) = (*)
instance Numeric a => Mul (Data a) (DVector a)
where
type Prod (Data a) (DVector a) = DVector a
(**) = distributeL (**)
instance Numeric a => Mul (DVector a) (Data a)
where
type Prod (DVector a) (Data a) = DVector a
(**) = distributeR (**)
instance Numeric a => Mul (Data a) (Matrix a)
where
type Prod (Data a) (Matrix a) = Matrix a
(**) = distributeL (**)
instance Numeric a => Mul (Matrix a) (Data a)
where
type Prod (Matrix a) (Data a) = Matrix a
(**) = distributeR (**)
instance Numeric a => Mul (DVector a) (DVector a)
where
type Prod (DVector a) (DVector a) = Data a
(**) = scalarProd
instance Numeric a => Mul (DVector a) (Matrix a)
where
type Prod (DVector a) (Matrix a) = (DVector a)
vec ** mat = distributeL (**) vec (transpose mat)
instance Numeric a => Mul (Matrix a) (DVector a)
where
type Prod (Matrix a) (DVector a) = (DVector a)
(**) = distributeR (**)
instance Numeric a => Mul (Matrix a) (Matrix a)
where
type Prod (Matrix a) (Matrix a) = (Matrix a)
(**) = distributeR (**)
mulMat :: Numeric a => Matrix a -> Matrix a -> Matrix a
mulMat = (**)
mul :: Numeric a => Matrix a -> Matrix a -> Matrix a
mul = (**)
class ElemWise a
where
type Elem a
elemWise :: (Elem a -> Elem a -> Elem a) -> a -> a -> a
instance ElemWise (Data a)
where
type Elem (Data a) = Data a
elemWise = id
instance ElemWise (DVector a)
where
type Elem (DVector a) = Data a
elemWise = zipWith
instance ElemWise (Matrix a)
where
type Elem (Matrix a) = Data a
elemWise = elemWise . elemWise
(.+) :: (ElemWise a, Num (Elem a)) => a -> a -> a
(.+) = elemWise (+)
(.-) :: (ElemWise a, Num (Elem a)) => a -> a -> a
(.-) = elemWise ()
(.*) :: (ElemWise a, Num (Elem a)) => a -> a -> a
(.*) = elemWise (*)