-- |
-- Module      : Data.VectorSpace.Free.Class
-- Copyright   : (c) Justus Sagemüller 2016
-- License     : GPL v3
-- 
-- Maintainer  : (@) jsag $ hvl.no
-- Stability   : experimental
-- Portability : portable
-- 
{-# LANGUAGE TypeFamilies            #-}
{-# LANGUAGE FlexibleContexts        #-}

module Data.VectorSpace.Free.Class ( FreeVectorSpace(..) ) where

import Data.VectorSpace
import Data.Ratio

import Foreign.C.Types (CFloat, CDouble, CSChar, CShort, CInt, CLong, CLLong, CIntMax)


-- | Vector spaces that are spanned by a specific, canonical set of basis vectors.
class (VectorSpace v, Num (Scalar v)) => FreeVectorSpace v where
  -- | Element-wise multiplication, equivalent to Matlab's @.*@ operator or
  --   @'L.liftI2' (*)@.
  (^*^) :: v -> v -> v
  -- | Like a monomorphic 'fmap'. Only guaranteed to act on the nonzero entries;
  --   whether the function is also applied on zeroes is instance-specific.
  vmap :: (Scalar v -> Scalar v) -> v -> v

instance FreeVectorSpace Float where {^*^ :: Float -> Float -> Float
(^*^) = Float -> Float -> Float
forall a. Num a => a -> a -> a
(*); vmap :: (Scalar Float -> Scalar Float) -> Float -> Float
vmap = (Scalar Float -> Scalar Float) -> Float -> Float
forall a. a -> a
id}
instance FreeVectorSpace Double where {^*^ :: Double -> Double -> Double
(^*^) = Double -> Double -> Double
forall a. Num a => a -> a -> a
(*); vmap :: (Scalar Double -> Scalar Double) -> Double -> Double
vmap = (Scalar Double -> Scalar Double) -> Double -> Double
forall a. a -> a
id}
instance FreeVectorSpace Int where {^*^ :: Int -> Int -> Int
(^*^) = Int -> Int -> Int
forall a. Num a => a -> a -> a
(*); vmap :: (Scalar Int -> Scalar Int) -> Int -> Int
vmap = (Scalar Int -> Scalar Int) -> Int -> Int
forall a. a -> a
id}
instance FreeVectorSpace Integer where {^*^ :: Integer -> Integer -> Integer
(^*^) = Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(*); vmap :: (Scalar Integer -> Scalar Integer) -> Integer -> Integer
vmap = (Scalar Integer -> Scalar Integer) -> Integer -> Integer
forall a. a -> a
id}
instance FreeVectorSpace CSChar where {^*^ :: CSChar -> CSChar -> CSChar
(^*^) = CSChar -> CSChar -> CSChar
forall a. Num a => a -> a -> a
(*); vmap :: (Scalar CSChar -> Scalar CSChar) -> CSChar -> CSChar
vmap = (Scalar CSChar -> Scalar CSChar) -> CSChar -> CSChar
forall a. a -> a
id}
instance FreeVectorSpace CShort where {^*^ :: CShort -> CShort -> CShort
(^*^) = CShort -> CShort -> CShort
forall a. Num a => a -> a -> a
(*); vmap :: (Scalar CShort -> Scalar CShort) -> CShort -> CShort
vmap = (Scalar CShort -> Scalar CShort) -> CShort -> CShort
forall a. a -> a
id}
instance FreeVectorSpace CInt where {^*^ :: CInt -> CInt -> CInt
(^*^) = CInt -> CInt -> CInt
forall a. Num a => a -> a -> a
(*); vmap :: (Scalar CInt -> Scalar CInt) -> CInt -> CInt
vmap = (Scalar CInt -> Scalar CInt) -> CInt -> CInt
forall a. a -> a
id}
instance FreeVectorSpace CLong where {^*^ :: CLong -> CLong -> CLong
(^*^) = CLong -> CLong -> CLong
forall a. Num a => a -> a -> a
(*); vmap :: (Scalar CLong -> Scalar CLong) -> CLong -> CLong
vmap = (Scalar CLong -> Scalar CLong) -> CLong -> CLong
forall a. a -> a
id}
instance FreeVectorSpace CLLong where {^*^ :: CLLong -> CLLong -> CLLong
(^*^) = CLLong -> CLLong -> CLLong
forall a. Num a => a -> a -> a
(*); vmap :: (Scalar CLLong -> Scalar CLLong) -> CLLong -> CLLong
vmap = (Scalar CLLong -> Scalar CLLong) -> CLLong -> CLLong
forall a. a -> a
id}
instance FreeVectorSpace CFloat where {^*^ :: CFloat -> CFloat -> CFloat
(^*^) = CFloat -> CFloat -> CFloat
forall a. Num a => a -> a -> a
(*); vmap :: (Scalar CFloat -> Scalar CFloat) -> CFloat -> CFloat
vmap = (Scalar CFloat -> Scalar CFloat) -> CFloat -> CFloat
forall a. a -> a
id}
instance FreeVectorSpace CDouble where {^*^ :: CDouble -> CDouble -> CDouble
(^*^) = CDouble -> CDouble -> CDouble
forall a. Num a => a -> a -> a
(*); vmap :: (Scalar CDouble -> Scalar CDouble) -> CDouble -> CDouble
vmap = (Scalar CDouble -> Scalar CDouble) -> CDouble -> CDouble
forall a. a -> a
id}
instance FreeVectorSpace CIntMax where {^*^ :: CIntMax -> CIntMax -> CIntMax
(^*^) = CIntMax -> CIntMax -> CIntMax
forall a. Num a => a -> a -> a
(*); vmap :: (Scalar CIntMax -> Scalar CIntMax) -> CIntMax -> CIntMax
vmap = (Scalar CIntMax -> Scalar CIntMax) -> CIntMax -> CIntMax
forall a. a -> a
id}
instance Integral a => FreeVectorSpace (Ratio a) where {^*^ :: Ratio a -> Ratio a -> Ratio a
(^*^) = Ratio a -> Ratio a -> Ratio a
forall a. Num a => a -> a -> a
(*); vmap :: (Scalar (Ratio a) -> Scalar (Ratio a)) -> Ratio a -> Ratio a
vmap = (Scalar (Ratio a) -> Scalar (Ratio a)) -> Ratio a -> Ratio a
forall a. a -> a
id}

instance (FreeVectorSpace v, FreeVectorSpace w, Scalar v ~ Scalar w)
               => FreeVectorSpace (v,w) where
  (v
v,w
w)^*^ :: (v, w) -> (v, w) -> (v, w)
^*^(v
v',w
w') = (v
vv -> v -> v
forall v. FreeVectorSpace v => v -> v -> v
^*^v
v', w
ww -> w -> w
forall v. FreeVectorSpace v => v -> v -> v
^*^w
w')
  vmap :: (Scalar (v, w) -> Scalar (v, w)) -> (v, w) -> (v, w)
vmap Scalar (v, w) -> Scalar (v, w)
f (v
v,w
w) = ((Scalar v -> Scalar v) -> v -> v
forall v. FreeVectorSpace v => (Scalar v -> Scalar v) -> v -> v
vmap Scalar v -> Scalar v
Scalar (v, w) -> Scalar (v, w)
f v
v, (Scalar w -> Scalar w) -> w -> w
forall v. FreeVectorSpace v => (Scalar v -> Scalar v) -> v -> v
vmap Scalar w -> Scalar w
Scalar (v, w) -> Scalar (v, w)
f w
w)
instance ( FreeVectorSpace u, FreeVectorSpace v, FreeVectorSpace w
         , Scalar v ~ Scalar u, Scalar v ~ Scalar w )
               => FreeVectorSpace (u,v,w) where
  (u
u,v
v,w
w)^*^ :: (u, v, w) -> (u, v, w) -> (u, v, w)
^*^(u
u',v
v',w
w') = (u
uu -> u -> u
forall v. FreeVectorSpace v => v -> v -> v
^*^u
u', v
vv -> v -> v
forall v. FreeVectorSpace v => v -> v -> v
^*^v
v', w
ww -> w -> w
forall v. FreeVectorSpace v => v -> v -> v
^*^w
w')
  vmap :: (Scalar (u, v, w) -> Scalar (u, v, w)) -> (u, v, w) -> (u, v, w)
vmap Scalar (u, v, w) -> Scalar (u, v, w)
f (u
u,v
v,w
w) = ((Scalar u -> Scalar u) -> u -> u
forall v. FreeVectorSpace v => (Scalar v -> Scalar v) -> v -> v
vmap Scalar u -> Scalar u
Scalar (u, v, w) -> Scalar (u, v, w)
f u
u, (Scalar v -> Scalar v) -> v -> v
forall v. FreeVectorSpace v => (Scalar v -> Scalar v) -> v -> v
vmap Scalar v -> Scalar v
Scalar (u, v, w) -> Scalar (u, v, w)
f v
v, (Scalar w -> Scalar w) -> w -> w
forall v. FreeVectorSpace v => (Scalar v -> Scalar v) -> v -> v
vmap Scalar w -> Scalar w
Scalar (u, v, w) -> Scalar (u, v, w)
f w
w)
instance ( FreeVectorSpace u, FreeVectorSpace v, FreeVectorSpace w, FreeVectorSpace x
         , Scalar x ~ Scalar v, Scalar v ~ Scalar u, Scalar v ~ Scalar w )
               => FreeVectorSpace (u,v,w,x) where
  (u
u,v
v,w
w,x
x)^*^ :: (u, v, w, x) -> (u, v, w, x) -> (u, v, w, x)
^*^(u
u',v
v',w
w',x
x') = (u
uu -> u -> u
forall v. FreeVectorSpace v => v -> v -> v
^*^u
u', v
vv -> v -> v
forall v. FreeVectorSpace v => v -> v -> v
^*^v
v', w
ww -> w -> w
forall v. FreeVectorSpace v => v -> v -> v
^*^w
w', x
xx -> x -> x
forall v. FreeVectorSpace v => v -> v -> v
^*^x
x')
  vmap :: (Scalar (u, v, w, x) -> Scalar (u, v, w, x))
-> (u, v, w, x) -> (u, v, w, x)
vmap Scalar (u, v, w, x) -> Scalar (u, v, w, x)
f (u
u,v
v,w
w,x
x) = ((Scalar u -> Scalar u) -> u -> u
forall v. FreeVectorSpace v => (Scalar v -> Scalar v) -> v -> v
vmap Scalar u -> Scalar u
Scalar (u, v, w, x) -> Scalar (u, v, w, x)
f u
u, (Scalar v -> Scalar v) -> v -> v
forall v. FreeVectorSpace v => (Scalar v -> Scalar v) -> v -> v
vmap Scalar v -> Scalar v
Scalar (u, v, w, x) -> Scalar (u, v, w, x)
f v
v, (Scalar w -> Scalar w) -> w -> w
forall v. FreeVectorSpace v => (Scalar v -> Scalar v) -> v -> v
vmap Scalar w -> Scalar w
Scalar (u, v, w, x) -> Scalar (u, v, w, x)
f w
w, (Scalar x -> Scalar x) -> x -> x
forall v. FreeVectorSpace v => (Scalar v -> Scalar v) -> v -> v
vmap Scalar x -> Scalar x
Scalar (u, v, w, x) -> Scalar (u, v, w, x)
f x
x)