-- |
-- Module      : Math.LinearMap.Category.TensorQuot
-- Copyright   : (c) Justus Sagemüller 2016
-- License     : GPL v3
-- 
-- Maintainer  : (@) jsag $ hvl.no
-- Stability   : experimental
-- Portability : portable
-- 


{-# LANGUAGE CPP                   #-}
{-# LANGUAGE TypeOperators         #-}
{-# LANGUAGE TypeFamilies          #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE UndecidableInstances  #-}
{-# LANGUAGE ScopedTypeVariables   #-}
{-# LANGUAGE UnicodeSyntax         #-}
{-# LANGUAGE TupleSections         #-}
{-# LANGUAGE ConstraintKinds       #-}

module Math.LinearMap.Category.TensorQuot where

import Math.LinearMap.Category.Class
import Math.LinearMap.Category.Instances
import Math.LinearMap.Asserted

import Data.VectorSpace
import Data.VectorSpace.Free

infixl 7 ·

class (TensorSpace v, VectorSpace w) => TensorQuot v w where
  type v  w :: *
  -- | Generalised multiplication operation. This subsumes '<.>^' and '*^'.
  --   For scalars therefore also '*', and for 'InnerSpace', '<.>'.
  (·) :: v  w -> v -> w

instance TensorQuot Double Double where
  type Double  Double = Double
  · :: (Double ⨸ Double) -> Double -> Double
(·) = (Double ⨸ Double) -> Double -> Double
forall a. Num a => a -> a -> a
(*)

instance ( TensorQuot x v, TensorQuot y w
         , Scalar x ~ Scalar y, Scalar v ~ Scalar w
         , (xv) ~ (yw) )
      => TensorQuot (x,y) (v,w) where
  type (x,y)  (v,w) = xv
  (x, y) ⨸ (v, w)
μ· :: ((x, y) ⨸ (v, w)) -> (x, y) -> (v, w)
·(x
x,y
y) = (x ⨸ v
(x, y) ⨸ (v, w)
μ(x ⨸ v) -> x -> v
forall v w. TensorQuot v w => (v ⨸ w) -> v -> w
·x
x, y ⨸ w
(x, y) ⨸ (v, w)
μ(y ⨸ w) -> y -> w
forall v w. TensorQuot v w => (v ⨸ w) -> v -> w
·y
y)
instance ( TensorQuot x Double, TensorQuot y Double
         , Scalar x ~ Double, Scalar y ~ Double )
      => TensorQuot (x,y) Double where
  type (x,y)  Double = (x  Double, y  Double)
  (v,w)· :: ((x, y) ⨸ Double) -> (x, y) -> Double
·(x
x,y
y) = x ⨸ Double
v(x ⨸ Double) -> x -> Double
forall v w. TensorQuot v w => (v ⨸ w) -> v -> w
·x
x Double -> Double -> Double
forall a. Num a => a -> a -> a
+ y ⨸ Double
w(y ⨸ Double) -> y -> Double
forall v w. TensorQuot v w => (v ⨸ w) -> v -> w
·y
y

#define FreeTensorQuot(V)                                \
instance (Num' s, Eq s) => TensorQuot (V s) (V s) where { \
  type V s ⨸ V s = s;                                      \
  (·) = (*^) };                                             \
instance TensorQuot (V Double) Double where {                \
  type V Double ⨸ Double = V Double;                          \
  (·) = (<.>) }

FreeTensorQuot(V1)
FreeTensorQuot(V2)
FreeTensorQuot(V3)
FreeTensorQuot(V4)

instance  s x y v w .
    ( TensorSpace v, TensorSpace w, v ~ x, LinearSpace y
    , TensorQuot x v, TensorQuot y w, (xv) ~ s, (yw) ~ s
    , Scalar x ~ s, Scalar y ~ s, Scalar v ~ s, Scalar w ~ s )
      => TensorQuot (Tensor s x y) (Tensor s v w) where
  type Tensor s x y  Tensor s v w = s
  Tensor s x y ⨸ Tensor s v w
μ· :: (Tensor s x y ⨸ Tensor s v w) -> Tensor s x y -> Tensor s v w
·Tensor s x y
t = (LinearFunction
  s
  (LinearFunction (Scalar w) y w)
  (LinearFunction s (Tensor s x y) (Tensor s v w))
forall v w x.
(TensorSpace v, TensorSpace w, TensorSpace x, Scalar w ~ Scalar v,
 Scalar x ~ Scalar v) =>
Bilinear (w -+> x) (v ⊗ w) (v ⊗ x)
fmapTensorLinearFunction
  s
  (LinearFunction (Scalar w) y w)
  (LinearFunction s (Tensor s x y) (Tensor s v w))
-> LinearFunction (Scalar w) y w
-> LinearFunction s (Tensor s x y) (Tensor s v w)
forall s v w. LinearFunction s v w -> v -> w
-+$>(y -> w) -> LinearFunction (Scalar w) y w
forall (f :: * -> * -> *) s u v.
(EnhancedCat f (LinearFunction s), LinearSpace u, TensorSpace v,
 Scalar u ~ s, Scalar v ~ s, Object f u, Object f v) =>
(u -> v) -> f u v
lfun(y ⨸ w
Tensor s x y ⨸ Tensor s v w
μ(y ⨸ w) -> y -> w
forall v w. TensorQuot v w => (v ⨸ w) -> v -> w
·))LinearFunction s (Tensor s x y) (Tensor s v w)
-> Tensor s x y -> Tensor s v w
forall s v w. LinearFunction s v w -> v -> w
-+$>Tensor s x y
t
instance ( LinearSpace x, LinearSpace y
         , s ~ Double, Scalar x ~ s, Scalar y ~ s )
      => TensorQuot (Tensor s x y) Double where
  type (Tensor s x y)  Double = DualVector (Tensor s x y)
  Tensor s x y ⨸ Double
f· :: (Tensor s x y ⨸ Double) -> Tensor s x y -> Double
·Tensor s x y
t = (LinearFunction
  Double
  (LinearMap Double x (DualVector y))
  (LinearFunction Double (Tensor s x y) Double)
forall v u.
(LinearSpace v, LinearSpace u, Scalar u ~ Scalar v) =>
Bilinear (DualVector (v ⊗ u)) (v ⊗ u) (Scalar v)
applyTensorFunctionalLinearFunction
  Double
  (LinearMap Double x (DualVector y))
  (LinearFunction Double (Tensor s x y) Double)
-> LinearMap Double x (DualVector y)
-> LinearFunction Double (Tensor s x y) Double
forall s v w. LinearFunction s v w -> v -> w
-+$>LinearMap Double x (DualVector y)
Tensor s x y ⨸ Double
f)LinearFunction Double (Tensor s x y) Double
-> Tensor s x y -> Double
forall s v w. LinearFunction s v w -> v -> w
-+$>Tensor s x y
t