-- Copyright (c) 2010, David Amos. All rights reserved. {-# LANGUAGE NoMonomorphismRestriction #-} -- |A module defining tensor products of vector spaces module Math.Algebras.TensorProduct where import Math.Algebras.VectorSpace data Tensor a b = T a b deriving (Eq, Ord, Show) -- or T !a !b, forcing strictness, but not proven to be better -- |Tensor product of two elements te :: Num k => Vect k a -> Vect k b -> Vect k (Tensor a b) te (V us) (V vs) = V [(T ei ej, xi*xj) | (ei,xi) <- us, (ej,xj) <- vs] -- preserves order - that is, if the inputs are correctly ordered, so is the output -- Implicit assumption - f and g are linear -- |Tensor product of two (linear) functions tf :: (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 [te (f $ V [(a, 1)]) (g $ V [(b, x)]) | (T a b, x) <- ts] where sum = foldl add zero -- (V []) -- tensor isomorphisms -- in fact, this definition works for any Functor f, not just (Vect k) assocL :: Vect k (Tensor u (Tensor v w)) -> Vect k (Tensor (Tensor u v) w) assocL = fmap (\(T a (T b c)) -> T (T a b) c) assocR :: Vect k (Tensor (Tensor u v) w) -> Vect k (Tensor u (Tensor v w)) assocR = fmap (\(T (T a b) c) -> T a (T b c)) inUnitL = fmap (\a -> T () a) inUnitR = fmap (\a -> T a ()) outUnitL = fmap (\(T () a) -> a) outUnitR = fmap (\(T a ()) -> a) twist v = nf $ fmap (\(T a b) -> T b a) v -- note the nf call, as f is not order-preserving