packages feed

HaskellForMaths-0.3.2: Math/Test/TAlgebras/TTensorProduct.hs

-- Copyright (c) 2010, David Amos. All rights reserved.

{-# LANGUAGE EmptyDataDecls, ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies, RankNTypes #-}

module Math.Test.TAlgebras.TTensorProduct where

import Test.QuickCheck
import Math.Algebras.VectorSpace
import Math.Algebras.TensorProduct
import Math.Algebra.Field.Base
import Math.Test.TAlgebras.TVectorSpace hiding (i1, i2)

import Prelude as P
import Control.Category as C
import Control.Arrow

type DirectSum k u v =
    (u ~ Vect k a, v ~ Vect k b) => Vect k (DSum a b)

type TensorProd k u v =
    (u ~ Vect k a, v ~ Vect k b) => Vect k (Tensor a b)

type En = Vect Q EBasis

{-
-- But then you need to make sure that you run GHCi with -XTypeFamilies, otherwise:

> e1 `te` e2 :: TensorProd Q En En
<interactive>:1:0:
    Illegal equational constraint En ~ Vect Q a
    (Use -XTypeFamilies to permit this)
    In an expression type signature: TensorProd Q En En
    In the expression: e1 `te` e2 :: TensorProd Q En En
    In the definition of `it': it = e1 `te` e2 :: TensorProd Q En En
-}


-- Now test eg
-- > quickCheck (\x -> (distrL . undistrL) x == id x)
-- but need to make x be of interesting type (not just () )


data Zero
-- a type with no inhabitants
-- so the associated free vector space is the zero space

-- instance Eq Zero where {}
-- instance Ord Zero where {}
instance Show Zero where {}

-- > zero :: Vect Q Zero
-- 0


-- ARROW INSTANCE
-- This isn't currently used anywhere else
-- It's intended to illustrate the point that tensor product is like doing things in parallel

newtype Linear k a b = Linear (Vect k a -> Vect k b)

instance Category (Linear k) where
    id = Linear P.id
    (Linear f) . (Linear g) = Linear (f P.. g)

instance Num k => Arrow (Linear k) where
    arr f = Linear (fmap f) -- requires nf call afterwards
    first (Linear f) = Linear $ \(V ts) -> V $
        concat [let V us = x *> te (f $ return a) (return c) in us | ((a,c),x) <- ts]
    second (Linear f) = Linear $ \(V ts) -> V $
        concat [let V us = x *> te (return c) (f $ return a) in us | ((c,a),x) <- ts]
    Linear f *** Linear g = Linear (f `tf2` g)
        where tf2 f g (V ts) = V $ concat
                  [let V us = x *> te (f $ return a) (g $ return b) in us | ((a,b), x) <- ts]
        -- can't use tf, as it uses add, which assumes Ord instance
        -- hence we should call nf afterwards
    -- !! What about &&&

{-
-- The following are morally correct, but don't work because they require Ord instance
instance Num k => ArrowChoice (Linear k) where
    left (Linear f) = Linear (f `dsume` id)
    right (Linear f) = Linear (id `dsume` f)
    Linear f +++ Linear g = Linear (f `dsumf` g)
    Linear f ||| Linear g = Linear (f `coprodf` g)
-}