{-# LANGUAGE CPP #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
-----------------------------------------------------------------------------

-- |

-- License     :  BSD-style (see the file LICENSE)

-- Maintainer  :  Edward Kmett <ekmett@gmail.com>

-- Stability   :  provisional

-- Portability :  portable

--

-----------------------------------------------------------------------------

module Linear.Algebra
  ( Algebra(..)
  , Coalgebra(..)
  , multRep, unitalRep
  , comultRep, counitalRep
  ) where

import Control.Lens hiding (index)
import Data.Functor.Rep
import Data.Complex
import Data.Void
import Linear.Vector
import Linear.Quaternion
import Linear.Conjugate
import Linear.V0
import Linear.V1
import Linear.V2
import Linear.V3
import Linear.V4

-- | An associative unital algebra over a ring

class Num r => Algebra r m where
  mult :: (m -> m -> r) -> m -> r
  unital :: r -> m -> r

multRep :: (Representable f, Algebra r (Rep f)) => f (f r) -> f r
multRep :: forall (f :: * -> *) r.
(Representable f, Algebra r (Rep f)) =>
f (f r) -> f r
multRep f (f r)
ffr = forall (f :: * -> *) a. Representable f => (Rep f -> a) -> f a
tabulate forall a b. (a -> b) -> a -> b
$ forall r m. Algebra r m => (m -> m -> r) -> m -> r
mult (forall (f :: * -> *) a. Representable f => f a -> Rep f -> a
index forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. Representable f => f a -> Rep f -> a
index f (f r)
ffr)

unitalRep :: (Representable f, Algebra r (Rep f)) => r -> f r
unitalRep :: forall (f :: * -> *) r.
(Representable f, Algebra r (Rep f)) =>
r -> f r
unitalRep = forall (f :: * -> *) a. Representable f => (Rep f -> a) -> f a
tabulate forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r m. Algebra r m => r -> m -> r
unital

instance Num r => Algebra r Void where
  mult :: (Void -> Void -> r) -> Void -> r
mult Void -> Void -> r
_ Void
_ = r
0
  unital :: r -> Void -> r
unital r
_ Void
_ = r
0

instance Num r => Algebra r (E V0) where
  mult :: (E V0 -> E V0 -> r) -> E V0 -> r
mult E V0 -> E V0 -> r
_ E V0
_ = r
0
  unital :: r -> E V0 -> r
unital r
_ E V0
_ = r
0

instance Num r => Algebra r (E V1) where
  mult :: (E V1 -> E V1 -> r) -> E V1 -> r
mult E V1 -> E V1 -> r
f E V1
_ = E V1 -> E V1 -> r
f forall (t :: * -> *). R1 t => E t
ex forall (t :: * -> *). R1 t => E t
ex
  unital :: r -> E V1 -> r
unital r
r E V1
_ = r
r

instance Num r => Algebra r () where
  mult :: (() -> () -> r) -> () -> r
mult () -> () -> r
f () = () -> () -> r
f () ()
  unital :: r -> () -> r
unital r
r () = r
r

instance (Algebra r a, Algebra r b) => Algebra r (a, b) where
  mult :: ((a, b) -> (a, b) -> r) -> (a, b) -> r
mult (a, b) -> (a, b) -> r
f (a
a,b
b) = forall r m. Algebra r m => (m -> m -> r) -> m -> r
mult (\a
a1 a
a2 -> forall r m. Algebra r m => (m -> m -> r) -> m -> r
mult (\b
b1 b
b2 -> (a, b) -> (a, b) -> r
f (a
a1,b
b1) (a
a2,b
b2)) b
b) a
a
  unital :: r -> (a, b) -> r
unital r
r (a
a,b
b) = forall r m. Algebra r m => r -> m -> r
unital r
r a
a forall a. Num a => a -> a -> a
* forall r m. Algebra r m => r -> m -> r
unital r
r b
b

instance Num r => Algebra r (E Complex) where
  mult :: (E Complex -> E Complex -> r) -> E Complex -> r
mult E Complex -> E Complex -> r
f = \ E Complex
i -> Complex r
cforall s a. s -> Getting a s a -> a
^.forall (t :: * -> *). E t -> forall x. Lens' (t x) x
el E Complex
i where
   c :: Complex r
c = (E Complex -> E Complex -> r
f forall (t :: * -> *). Complicated t => E t
ee forall (t :: * -> *). Complicated t => E t
ee forall a. Num a => a -> a -> a
- E Complex -> E Complex -> r
f forall (t :: * -> *). Complicated t => E t
ei forall (t :: * -> *). Complicated t => E t
ei) forall a. a -> a -> Complex a
:+ (E Complex -> E Complex -> r
f forall (t :: * -> *). Complicated t => E t
ee forall (t :: * -> *). Complicated t => E t
ei forall a. Num a => a -> a -> a
+ E Complex -> E Complex -> r
f forall (t :: * -> *). Complicated t => E t
ei forall (t :: * -> *). Complicated t => E t
ee)
  unital :: r -> E Complex -> r
unital r
r E Complex
i = (r
r forall a. a -> a -> Complex a
:+ r
0)forall s a. s -> Getting a s a -> a
^.forall (t :: * -> *). E t -> forall x. Lens' (t x) x
el E Complex
i

instance (Num r, TrivialConjugate r) => Algebra r (E Quaternion) where
  mult :: (E Quaternion -> E Quaternion -> r) -> E Quaternion -> r
mult E Quaternion -> E Quaternion -> r
f = forall (f :: * -> *) a. Representable f => f a -> Rep f -> a
index forall a b. (a -> b) -> a -> b
$ forall a. a -> V3 a -> Quaternion a
Quaternion
    (E Quaternion -> E Quaternion -> r
f forall (t :: * -> *). Complicated t => E t
ee forall (t :: * -> *). Complicated t => E t
ee forall a. Num a => a -> a -> a
- (E Quaternion -> E Quaternion -> r
f forall (t :: * -> *). Complicated t => E t
ei forall (t :: * -> *). Complicated t => E t
ei forall a. Num a => a -> a -> a
+ E Quaternion -> E Quaternion -> r
f forall (t :: * -> *). Hamiltonian t => E t
ej forall (t :: * -> *). Hamiltonian t => E t
ej forall a. Num a => a -> a -> a
+ E Quaternion -> E Quaternion -> r
f forall (t :: * -> *). Hamiltonian t => E t
ek forall (t :: * -> *). Hamiltonian t => E t
ek))
    (forall a. a -> a -> a -> V3 a
V3 (E Quaternion -> E Quaternion -> r
f forall (t :: * -> *). Complicated t => E t
ee forall (t :: * -> *). Complicated t => E t
ei forall a. Num a => a -> a -> a
+ E Quaternion -> E Quaternion -> r
f forall (t :: * -> *). Complicated t => E t
ei forall (t :: * -> *). Complicated t => E t
ee forall a. Num a => a -> a -> a
+ E Quaternion -> E Quaternion -> r
f forall (t :: * -> *). Hamiltonian t => E t
ej forall (t :: * -> *). Hamiltonian t => E t
ek forall a. Num a => a -> a -> a
- E Quaternion -> E Quaternion -> r
f forall (t :: * -> *). Hamiltonian t => E t
ek forall (t :: * -> *). Hamiltonian t => E t
ej)
        (E Quaternion -> E Quaternion -> r
f forall (t :: * -> *). Complicated t => E t
ee forall (t :: * -> *). Hamiltonian t => E t
ej forall a. Num a => a -> a -> a
+ E Quaternion -> E Quaternion -> r
f forall (t :: * -> *). Hamiltonian t => E t
ej forall (t :: * -> *). Complicated t => E t
ee forall a. Num a => a -> a -> a
+ E Quaternion -> E Quaternion -> r
f forall (t :: * -> *). Hamiltonian t => E t
ek forall (t :: * -> *). Complicated t => E t
ei forall a. Num a => a -> a -> a
- E Quaternion -> E Quaternion -> r
f forall (t :: * -> *). Complicated t => E t
ei forall (t :: * -> *). Hamiltonian t => E t
ek)
        (E Quaternion -> E Quaternion -> r
f forall (t :: * -> *). Complicated t => E t
ee forall (t :: * -> *). Hamiltonian t => E t
ek forall a. Num a => a -> a -> a
+ E Quaternion -> E Quaternion -> r
f forall (t :: * -> *). Hamiltonian t => E t
ek forall (t :: * -> *). Complicated t => E t
ee forall a. Num a => a -> a -> a
+ E Quaternion -> E Quaternion -> r
f forall (t :: * -> *). Complicated t => E t
ei forall (t :: * -> *). Hamiltonian t => E t
ej forall a. Num a => a -> a -> a
- E Quaternion -> E Quaternion -> r
f forall (t :: * -> *). Hamiltonian t => E t
ej forall (t :: * -> *). Complicated t => E t
ei))
  unital :: r -> E Quaternion -> r
unital r
r = forall (f :: * -> *) a. Representable f => f a -> Rep f -> a
index (forall a. a -> V3 a -> Quaternion a
Quaternion r
r V3 r
0)

-- | A coassociative counital coalgebra over a ring

class Num r => Coalgebra r m where
  comult :: (m -> r) -> m -> m -> r
  counital :: (m -> r) -> r

comultRep :: (Representable f, Coalgebra r (Rep f)) => f r -> f (f r)
comultRep :: forall (f :: * -> *) r.
(Representable f, Coalgebra r (Rep f)) =>
f r -> f (f r)
comultRep f r
fr = forall (f :: * -> *) a. Representable f => (Rep f -> a) -> f a
tabulate forall a b. (a -> b) -> a -> b
$ \Rep f
i -> forall (f :: * -> *) a. Representable f => (Rep f -> a) -> f a
tabulate forall a b. (a -> b) -> a -> b
$ \Rep f
j -> forall r m. Coalgebra r m => (m -> r) -> m -> m -> r
comult (forall (f :: * -> *) a. Representable f => f a -> Rep f -> a
index f r
fr) Rep f
i Rep f
j

counitalRep :: (Representable f, Coalgebra r (Rep f)) => f r -> r
counitalRep :: forall (f :: * -> *) r.
(Representable f, Coalgebra r (Rep f)) =>
f r -> r
counitalRep = forall r m. Coalgebra r m => (m -> r) -> r
counital forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. Representable f => f a -> Rep f -> a
index

instance Num r => Coalgebra r Void where
  comult :: (Void -> r) -> Void -> Void -> r
comult Void -> r
_ Void
_ Void
_ = r
0
  counital :: (Void -> r) -> r
counital Void -> r
_ = r
0

instance Num r => Coalgebra r () where
  comult :: (() -> r) -> () -> () -> r
comult () -> r
f () () = () -> r
f ()
  counital :: (() -> r) -> r
counital () -> r
f = () -> r
f ()

instance Num r => Coalgebra r (E V0) where
  comult :: (E V0 -> r) -> E V0 -> E V0 -> r
comult E V0 -> r
_ E V0
_ E V0
_ = r
0
  counital :: (E V0 -> r) -> r
counital E V0 -> r
_ = r
0

instance Num r => Coalgebra r (E V1) where
  comult :: (E V1 -> r) -> E V1 -> E V1 -> r
comult E V1 -> r
f E V1
_ E V1
_ = E V1 -> r
f forall (t :: * -> *). R1 t => E t
ex
  counital :: (E V1 -> r) -> r
counital E V1 -> r
f = E V1 -> r
f forall (t :: * -> *). R1 t => E t
ex

instance Num r => Coalgebra r (E V2) where
  comult :: (E V2 -> r) -> E V2 -> E V2 -> r
comult E V2 -> r
f = forall (f :: * -> *) a. Representable f => f a -> Rep f -> a
index forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. Representable f => f a -> Rep f -> a
index V2 (V2 r)
v where
    v :: V2 (V2 r)
v = forall a. a -> a -> V2 a
V2 (forall a. a -> a -> V2 a
V2 (E V2 -> r
f forall (t :: * -> *). R1 t => E t
ex) r
0) (forall a. a -> a -> V2 a
V2 r
0 (E V2 -> r
f forall (t :: * -> *). R2 t => E t
ey))
  counital :: (E V2 -> r) -> r
counital E V2 -> r
f = E V2 -> r
f forall (t :: * -> *). R1 t => E t
ex forall a. Num a => a -> a -> a
+ E V2 -> r
f forall (t :: * -> *). R2 t => E t
ey

instance Num r => Coalgebra r (E V3) where
  comult :: (E V3 -> r) -> E V3 -> E V3 -> r
comult E V3 -> r
f = forall (f :: * -> *) a. Representable f => f a -> Rep f -> a
index forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. Representable f => f a -> Rep f -> a
index V3 (V3 r)
q where
    q :: V3 (V3 r)
q = forall a. a -> a -> a -> V3 a
V3 (forall a. a -> a -> a -> V3 a
V3 (E V3 -> r
f forall (t :: * -> *). R1 t => E t
ex) r
0 r
0)
           (forall a. a -> a -> a -> V3 a
V3 r
0 (E V3 -> r
f forall (t :: * -> *). R2 t => E t
ey) r
0)
           (forall a. a -> a -> a -> V3 a
V3 r
0 r
0 (E V3 -> r
f forall (t :: * -> *). R3 t => E t
ez))
  counital :: (E V3 -> r) -> r
counital E V3 -> r
f = E V3 -> r
f forall (t :: * -> *). R1 t => E t
ex forall a. Num a => a -> a -> a
+ E V3 -> r
f forall (t :: * -> *). R2 t => E t
ey forall a. Num a => a -> a -> a
+ E V3 -> r
f forall (t :: * -> *). R3 t => E t
ez

instance Num r => Coalgebra r (E V4) where
  comult :: (E V4 -> r) -> E V4 -> E V4 -> r
comult E V4 -> r
f = forall (f :: * -> *) a. Representable f => f a -> Rep f -> a
index forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. Representable f => f a -> Rep f -> a
index V4 (V4 r)
v where
    v :: V4 (V4 r)
v = forall a. a -> a -> a -> a -> V4 a
V4 (forall a. a -> a -> a -> a -> V4 a
V4 (E V4 -> r
f forall (t :: * -> *). R1 t => E t
ex) r
0 r
0 r
0) (forall a. a -> a -> a -> a -> V4 a
V4 r
0 (E V4 -> r
f forall (t :: * -> *). R2 t => E t
ey) r
0 r
0) (forall a. a -> a -> a -> a -> V4 a
V4 r
0 r
0 (E V4 -> r
f forall (t :: * -> *). R3 t => E t
ez) r
0) (forall a. a -> a -> a -> a -> V4 a
V4 r
0 r
0 r
0 (E V4 -> r
f forall (t :: * -> *). R4 t => E t
ew))
  counital :: (E V4 -> r) -> r
counital E V4 -> r
f = E V4 -> r
f forall (t :: * -> *). R1 t => E t
ex forall a. Num a => a -> a -> a
+ E V4 -> r
f forall (t :: * -> *). R2 t => E t
ey forall a. Num a => a -> a -> a
+ E V4 -> r
f forall (t :: * -> *). R3 t => E t
ez forall a. Num a => a -> a -> a
+ E V4 -> r
f forall (t :: * -> *). R4 t => E t
ew

instance Num r => Coalgebra r (E Complex) where
  comult :: (E Complex -> r) -> E Complex -> E Complex -> r
comult E Complex -> r
f = \E Complex
i E Complex
j -> Complex (Complex r)
cforall s a. s -> Getting a s a -> a
^.forall (t :: * -> *). E t -> forall x. Lens' (t x) x
el E Complex
iforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall (t :: * -> *). E t -> forall x. Lens' (t x) x
el E Complex
j where
    c :: Complex (Complex r)
c = (E Complex -> r
f forall (t :: * -> *). Complicated t => E t
ee forall a. a -> a -> Complex a
:+ r
0) forall a. a -> a -> Complex a
:+ (r
0 forall a. a -> a -> Complex a
:+ E Complex -> r
f forall (t :: * -> *). Complicated t => E t
ei)
  counital :: (E Complex -> r) -> r
counital E Complex -> r
f = E Complex -> r
f forall (t :: * -> *). Complicated t => E t
ee forall a. Num a => a -> a -> a
+ E Complex -> r
f forall (t :: * -> *). Complicated t => E t
ei

instance (Num r, TrivialConjugate r) => Coalgebra r (E Quaternion) where
  comult :: (E Quaternion -> r) -> E Quaternion -> E Quaternion -> r
comult E Quaternion -> r
f = forall (f :: * -> *) a. Representable f => f a -> Rep f -> a
index forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. Representable f => f a -> Rep f -> a
index
    (forall a. a -> V3 a -> Quaternion a
Quaternion (forall a. a -> V3 a -> Quaternion a
Quaternion (E Quaternion -> r
f forall (t :: * -> *). Complicated t => E t
ee) (forall a. a -> a -> a -> V3 a
V3 r
0 r
0 r
0))
            (forall a. a -> a -> a -> V3 a
V3 (forall a. a -> V3 a -> Quaternion a
Quaternion r
0 (forall a. a -> a -> a -> V3 a
V3 (E Quaternion -> r
f forall (t :: * -> *). Complicated t => E t
ei) r
0 r
0))
                (forall a. a -> V3 a -> Quaternion a
Quaternion r
0 (forall a. a -> a -> a -> V3 a
V3 r
0 (E Quaternion -> r
f forall (t :: * -> *). Hamiltonian t => E t
ej) r
0))
                (forall a. a -> V3 a -> Quaternion a
Quaternion r
0 (forall a. a -> a -> a -> V3 a
V3 r
0 r
0 (E Quaternion -> r
f forall (t :: * -> *). Hamiltonian t => E t
ek)))))
  counital :: (E Quaternion -> r) -> r
counital E Quaternion -> r
f = E Quaternion -> r
f forall (t :: * -> *). Complicated t => E t
ee forall a. Num a => a -> a -> a
+ E Quaternion -> r
f forall (t :: * -> *). Complicated t => E t
ei forall a. Num a => a -> a -> a
+ E Quaternion -> r
f forall (t :: * -> *). Hamiltonian t => E t
ej forall a. Num a => a -> a -> a
+ E Quaternion -> r
f forall (t :: * -> *). Hamiltonian t => E t
ek

instance (Coalgebra r m, Coalgebra r n) => Coalgebra r (m, n) where
  comult :: ((m, n) -> r) -> (m, n) -> (m, n) -> r
comult (m, n) -> r
f (m
a1, n
b1) (m
a2, n
b2) = forall r m. Coalgebra r m => (m -> r) -> m -> m -> r
comult (\m
a -> forall r m. Coalgebra r m => (m -> r) -> m -> m -> r
comult (\n
b -> (m, n) -> r
f (m
a, n
b)) n
b1 n
b2) m
a1 m
a2
  counital :: ((m, n) -> r) -> r
counital (m, n) -> r
k = forall r m. Coalgebra r m => (m -> r) -> r
counital forall a b. (a -> b) -> a -> b
$ \m
a -> forall r m. Coalgebra r m => (m -> r) -> r
counital forall a b. (a -> b) -> a -> b
$ \n
b -> (m, n) -> r
k (m
a,n
b)