{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Numeric.Matrix (
) where
import Internal.Vector
import Internal.Matrix
import Internal.Element
import Internal.Numeric
import qualified Data.Monoid as M
import Data.List(partition)
import qualified Data.Foldable as F
import qualified Data.Semigroup as S
import Internal.Chain
import Foreign.Storable(Storable)
instance Container Matrix a => Eq (Matrix a) where
(==) = equal
instance (Container Matrix a, Num a, Num (Vector a)) => Num (Matrix a) where
(+) = liftMatrix2Auto (+)
(-) = liftMatrix2Auto (-)
negate = liftMatrix negate
(*) = liftMatrix2Auto (*)
signum = liftMatrix signum
abs = liftMatrix abs
fromInteger = (1><1) . return . fromInteger
instance (Container Vector a, Fractional a, Fractional (Vector a), Num (Matrix a)) => Fractional (Matrix a) where
fromRational n = (1><1) [fromRational n]
(/) = liftMatrix2Auto (/)
instance (Floating a, Container Vector a, Floating (Vector a), Fractional (Matrix a)) => Floating (Matrix a) where
sin = liftMatrix sin
cos = liftMatrix cos
tan = liftMatrix tan
asin = liftMatrix asin
acos = liftMatrix acos
atan = liftMatrix atan
sinh = liftMatrix sinh
cosh = liftMatrix cosh
tanh = liftMatrix tanh
asinh = liftMatrix asinh
acosh = liftMatrix acosh
atanh = liftMatrix atanh
exp = liftMatrix exp
log = liftMatrix log
(**) = liftMatrix2Auto (**)
sqrt = liftMatrix sqrt
pi = (1><1) [pi]
isScalar :: Matrix t -> Bool
isScalar m = rows m == 1 && cols m == 1
adaptScalarM :: (Foreign.Storable.Storable t1, Foreign.Storable.Storable t2)
=> (t1 -> Matrix t2 -> t)
-> (Matrix t1 -> Matrix t2 -> t)
-> (Matrix t1 -> t2 -> t)
-> Matrix t1
-> Matrix t2
-> t
adaptScalarM f1 f2 f3 x y
| isScalar x = f1 (x @@>(0,0) ) y
| isScalar y = f3 x (y @@>(0,0) )
| otherwise = f2 x y
instance (Container Vector t, Eq t, Num (Vector t), Product t) => S.Semigroup (Matrix t)
where
(<>) = mappend
sconcat = mconcat . F.toList
instance (Container Vector t, Eq t, Num (Vector t), Product t) => M.Monoid (Matrix t)
where
mempty = 1
mappend = adaptScalarM scale mXm (flip scale)
mconcat xs = work (partition isScalar xs)
where
work (ss,[]) = product ss
work (ss,ms) = scl (product ss) (optimiseMult ms)
scl x m
| isScalar x && x00 == 1 = m
| otherwise = scale x00 m
where
x00 = x @@> (0,0)