module Numeric.LinearAlgebra.Linear (
Linear(..),
multiply, dot, outer, kronecker
) where
import Data.Packed.Internal(multiply,partit)
import Data.Packed
import Numeric.GSL.Vector
import Complex
class (Container c e) => Linear c e where
scale :: e -> c e -> c e
addConstant :: e -> c e -> c e
add :: c e -> c e -> c e
sub :: c e -> c e -> c e
mul :: c e -> c e -> c e
divide :: c e -> c e -> c e
scaleRecip :: e -> c e -> c e
equal :: c e -> c e -> Bool
instance Linear Vector Double where
scale = vectorMapValR Scale
scaleRecip = vectorMapValR Recip
addConstant = vectorMapValR AddConstant
add = vectorZipR Add
sub = vectorZipR Sub
mul = vectorZipR Mul
divide = vectorZipR Div
equal u v = dim u == dim v && vectorMax (vectorMapR Abs (sub u v)) == 0.0
instance Linear Vector (Complex Double) where
scale = vectorMapValC Scale
scaleRecip = vectorMapValC Recip
addConstant = vectorMapValC AddConstant
add = vectorZipC Add
sub = vectorZipC Sub
mul = vectorZipC Mul
divide = vectorZipC Div
equal u v = dim u == dim v && vectorMax (liftVector magnitude (sub u v)) == 0.0
instance (Linear Vector a, Container Matrix a) => (Linear Matrix a) where
scale x = liftMatrix (scale x)
scaleRecip x = liftMatrix (scaleRecip x)
addConstant x = liftMatrix (addConstant x)
add = liftMatrix2 add
sub = liftMatrix2 sub
mul = liftMatrix2 mul
divide = liftMatrix2 divide
equal a b = cols a == cols b && flatten a `equal` flatten b
dot :: (Element t) => Vector t -> Vector t -> t
dot u v = multiply r c @@> (0,0)
where r = asRow u
c = asColumn v
outer :: (Element t) => Vector t -> Vector t -> Matrix t
outer u v = asColumn u `multiply` asRow v
kronecker :: (Element t) => Matrix t -> Matrix t -> Matrix t
kronecker a b = fromBlocks
. partit (cols a)
. map (reshape (cols b))
. toRows
$ flatten a `outer` flatten b