{-# LANGUAGE NoMonomorphismRestriction #-}
module Math.Algebras.TensorProduct where
import Prelude hiding ( (*>) )
import Math.Algebras.VectorSpace
infix 7 `te`, `tf`
infix 6 `dsume`, `dsumf`
type DSum a b = Either a b
i1 :: Vect k a -> Vect k (DSum a b)
i1 = fmap Left
i2 :: Vect k b -> Vect k (DSum a b)
i2 = fmap Right
coprodf :: (Eq k, Num k, Ord t) =>
(Vect k a -> Vect k t) -> (Vect k b -> Vect k t) -> Vect k (DSum a b) -> Vect k t
coprodf f g = linear fg' where
fg' (Left a) = f (return a)
fg' (Right b) = g (return b)
p1 :: (Eq k, Num k, Ord a) => Vect k (DSum a b) -> Vect k a
p1 = linear p1' where
p1' (Left a) = return a
p1' (Right b) = zerov
p2 :: (Eq k, Num k, Ord b) => Vect k (DSum a b) -> Vect k b
p2 = linear p2' where
p2' (Left a) = zerov
p2' (Right b) = return b
prodf :: (Eq k, Num k, Ord a, Ord b) =>
(Vect k s -> Vect k a) -> (Vect k s -> Vect k b) -> Vect k s -> Vect k (DSum a b)
prodf f g = linear fg' where
fg' b = fmap Left (f $ return b) <+> fmap Right (g $ return b)
dsume :: (Eq k, Num k, Ord a, Ord b) => Vect k a -> Vect k b -> Vect k (DSum a b)
dsume x y = i1 x <+> i2 y
dsumf :: (Eq k, Num k, Ord a, Ord b, Ord a', Ord b') =>
(Vect k a -> Vect k a') -> (Vect k b -> Vect k b') -> Vect k (DSum a b) -> Vect k (DSum a' b')
dsumf f g ab = (i1 . f . p1) ab <+> (i2 . g . p2) ab
type Tensor a b = (a,b)
te :: Num k => Vect k a -> Vect k b -> Vect k (Tensor a b)
te (V us) (V vs) = V [((a,b), x*y) | (a,x) <- us, (b,y) <- vs]
tf :: (Eq k, Num k, Ord a', Ord b') => (Vect k a -> Vect k a') -> (Vect k b -> Vect k b')
-> Vect k (Tensor a b) -> Vect k (Tensor a' b')
tf f g (V ts) = sum [x *> te (f $ return a) (g $ return b) | ((a,b), x) <- ts]
where sum = foldl add zerov
assocL :: Vect k (Tensor a (Tensor b c)) -> Vect k (Tensor (Tensor a b) c)
assocL = fmap ( \(a,(b,c)) -> ((a,b),c) )
assocR :: Vect k (Tensor (Tensor a b) c) -> Vect k (Tensor a (Tensor b c))
assocR = fmap ( \((a,b),c) -> (a,(b,c)) )
unitInL :: Vect k a -> Vect k (Tensor () a)
unitInL = fmap ( \a -> ((),a) )
unitOutL :: Vect k (Tensor () a) -> Vect k a
unitOutL = fmap ( \((),a) -> a )
unitInR :: Vect k a -> Vect k (Tensor a ())
unitInR = fmap ( \a -> (a,()) )
unitOutR :: Vect k (Tensor a ()) -> Vect k a
unitOutR = fmap ( \(a,()) -> a )
twist :: (Eq k, Num k, Ord a, Ord b) => Vect k (Tensor a b) -> Vect k (Tensor b a)
twist v = nf $ fmap ( \(a,b) -> (b,a) ) v
distrL :: (Eq k, Num k, Ord a, Ord b, Ord c)
=> Vect k (Tensor a (DSum b c)) -> Vect k (DSum (Tensor a b) (Tensor a c))
distrL v = nf $ fmap (\(a,bc) -> case bc of Left b -> Left (a,b); Right c -> Right (a,c)) v
undistrL :: (Eq k, Num k, Ord a, Ord b, Ord c)
=> Vect k (DSum (Tensor a b) (Tensor a c)) -> Vect k (Tensor a (DSum b c))
undistrL v = nf $ fmap ( \abc -> case abc of Left (a,b) -> (a,Left b); Right (a,c) -> (a,Right c) ) v
distrR :: Vect k (Tensor (DSum a b) c) -> Vect k (DSum (Tensor a c) (Tensor b c))
distrR v = fmap ( \(ab,c) -> case ab of Left a -> Left (a,c); Right b -> Right (b,c) ) v
undistrR :: Vect k (DSum (Tensor a c) (Tensor b c)) -> Vect k (Tensor (DSum a b) c)
undistrR v = fmap ( \abc -> case abc of Left (a,c) -> (Left a, c); Right (b,c) -> (Right b, c) ) v
ev :: (Eq k, Num k, Ord b) => Vect k (Tensor (Dual b) b) -> k
ev = unwrap . linear (\(Dual bi, bj) -> delta bi bj *> return ())
delta i j = if i == j then 1 else 0
reify :: (Eq k, Num k, Ord b) => Vect k (Dual b) -> (Vect k b -> k)
reify f x = ev (f `te` x)