{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Data.VectorSpace where
infixr 6 *^
infixl 6 ^/
infix 6 `dot`
infixl 5 ^+^, ^-^
class Num (Groundring v) => RModule v where
type Groundring v
zeroVector :: v
(*^) :: Groundring v -> v -> v
(*^) = flip (^*)
(^*) :: v -> Groundring v -> v
(^*) = flip (*^)
negateVector :: v -> v
negateVector v = (-1) *^ v
(^+^) :: v -> v -> v
(^-^) :: v -> v -> v
v1 ^-^ v2 = v1 ^+^ negateVector v2
class (Fractional (Groundring v), RModule v) => VectorSpace v where
(^/) :: v -> Groundfield v -> v
v ^/ a = (1/a) *^ v
type Groundfield v = Groundring v
class RModule v => InnerProductSpace v where
dot :: v -> v -> Groundfield v
class (Floating (Groundfield v), InnerProductSpace v, VectorSpace v) => NormedSpace v where
norm :: v -> Groundfield v
norm v = sqrt $ v `dot` v
normalize :: (Eq (Groundfield v), NormedSpace v) => v -> v
normalize v = if nv /= 0 then v ^/ nv else error "normalize: zero vector"
where nv = norm v
instance RModule Int where
type Groundring Int = Int
(^+^) = (+)
(^*) = (*)
zeroVector = 0
instance RModule Integer where
type Groundring Integer = Integer
(^+^) = (+)
(^*) = (*)
zeroVector = 0
instance RModule Double where
type Groundring Double = Double
(^+^) = (+)
(^*) = (*)
zeroVector = 0
instance RModule Float where
type Groundring Float = Float
(^+^) = (+)
(^*) = (*)
zeroVector = 0
instance VectorSpace Double where
instance VectorSpace Float where
instance
( Groundring a ~ Groundring b
, RModule a, RModule b
) => RModule (a, b) where
type Groundring (a, b) = Groundring a
zeroVector = (zeroVector, zeroVector)
(a, b) ^* x = (a ^* x, b ^* x)
(a1, b1) ^+^ (a2, b2) = (a1 ^+^ a2, b1 ^+^ b2)
instance
(Groundfield a ~ Groundfield b
, VectorSpace a, VectorSpace b
) => VectorSpace (a, b) where
(a, b) ^/ x = (a ^/ x, b ^/ x)
instance (Groundfield a ~ Groundfield b, InnerProductSpace a, InnerProductSpace b) => InnerProductSpace (a, b) where
(a1, b1) `dot` (a2, b2) = (a1 `dot` a2) + (b1 `dot` b2)
instance (Groundfield a ~ Groundfield b, NormedSpace a, NormedSpace b) => NormedSpace (a, b) where
break3Tuple :: (a, b, c) -> ((a, b), c)
break3Tuple (a, b, c) = ((a, b), c)
join3Tuple :: ((a, b), c) -> (a, b, c)
join3Tuple ((a, b), c) = (a, b, c)
break4Tuple :: (a, b, c, d) -> ((a, b), (c, d))
break4Tuple (a, b, c, d) = ((a, b), (c, d))
join4Tuple :: ((a, b), (c, d)) -> (a, b, c, d)
join4Tuple ((a, b), (c, d)) = (a, b, c, d)
break5Tuple :: (a, b, c, d, e) -> ((a, b), (c, d, e))
break5Tuple (a, b, c, d, e) = ((a, b), (c, d, e))
join5Tuple :: ((a, b), (c, d, e)) -> (a, b, c, d, e)
join5Tuple ((a, b), (c, d, e)) = (a, b, c, d, e)
instance
( Groundring a ~ Groundring b
, Groundring a ~ Groundring c
, RModule a, RModule b, RModule c
) => RModule (a, b, c) where
type Groundring (a, b, c) = Groundring a
zeroVector = join3Tuple zeroVector
a *^ v = join3Tuple $ a *^ (break3Tuple v)
v1 ^+^ v2 = join3Tuple $ break3Tuple v1 ^+^ break3Tuple v2
instance
( Groundring a ~ Groundring b
, Groundring a ~ Groundring c
, VectorSpace a, VectorSpace b, VectorSpace c
) => VectorSpace (a, b, c) where
instance
( Groundring a ~ Groundring b
, Groundring a ~ Groundring c
, InnerProductSpace a, InnerProductSpace b, InnerProductSpace c
) => InnerProductSpace (a, b, c) where
v1 `dot` v2 = break3Tuple v1 `dot` break3Tuple v2
instance
( Groundring a ~ Groundring b
, Groundring a ~ Groundring c
, NormedSpace a, NormedSpace b, NormedSpace c
) => NormedSpace (a, b, c) where
instance
( Groundring a ~ Groundring b
, Groundring a ~ Groundring c
, Groundring a ~ Groundring d
, RModule a, RModule b, RModule c, RModule d
) => RModule (a, b, c, d) where
type Groundring (a, b, c, d) = Groundring a
zeroVector = join4Tuple zeroVector
a *^ v = join4Tuple $ a *^ (break4Tuple v)
v1 ^+^ v2 = join4Tuple $ break4Tuple v1 ^+^ break4Tuple v2
instance
( Groundring a ~ Groundring b
, Groundring a ~ Groundring c
, Groundring a ~ Groundring d
, VectorSpace a, VectorSpace b, VectorSpace c, VectorSpace d
) => VectorSpace (a, b, c, d) where
instance
( Groundring a ~ Groundring b
, Groundring a ~ Groundring c
, Groundring a ~ Groundring d
, InnerProductSpace a, InnerProductSpace b
, InnerProductSpace c, InnerProductSpace d
) => InnerProductSpace (a, b, c, d) where
v1 `dot` v2 = break4Tuple v1 `dot` break4Tuple v2
instance
( Groundring a ~ Groundring b
, Groundring a ~ Groundring c
, Groundring a ~ Groundring d
, NormedSpace a, NormedSpace b, NormedSpace c, NormedSpace d
) => NormedSpace (a, b, c, d) where
instance
( Groundring a ~ Groundring b
, Groundring a ~ Groundring c
, Groundring a ~ Groundring d
, Groundring a ~ Groundring e
, RModule a, RModule b, RModule c, RModule d, RModule e
) => RModule (a, b, c, d, e) where
type Groundring (a, b, c, d, e) = Groundring a
zeroVector = join5Tuple zeroVector
a *^ v = join5Tuple $ a *^ (break5Tuple v)
v1 ^+^ v2 = join5Tuple $ break5Tuple v1 ^+^ break5Tuple v2
instance
( Groundring a ~ Groundring b
, Groundring a ~ Groundring c
, Groundring a ~ Groundring d
, Groundring a ~ Groundring e
, VectorSpace a, VectorSpace b, VectorSpace c, VectorSpace d, VectorSpace e
) => VectorSpace (a, b, c, d, e) where
instance
( Groundring a ~ Groundring b
, Groundring a ~ Groundring c
, Groundring a ~ Groundring d
, Groundring a ~ Groundring e
, InnerProductSpace a, InnerProductSpace b, InnerProductSpace c
, InnerProductSpace d, InnerProductSpace e
) => InnerProductSpace (a, b, c, d, e) where
v1 `dot` v2 = break5Tuple v1 `dot` break5Tuple v2
instance
( Groundring a ~ Groundring b
, Groundring a ~ Groundring c
, Groundring a ~ Groundring d
, Groundring a ~ Groundring e
, NormedSpace a, NormedSpace b, NormedSpace c, NormedSpace d, NormedSpace e
) => NormedSpace (a, b, c, d, e) where
newtype FractionalVectorSpace a = FractionalVectorSpace { getFractional :: a }
deriving (Num, Fractional)
instance Num a => RModule (FractionalVectorSpace a) where
type Groundring (FractionalVectorSpace a) = a
v1 ^+^ v2 = FractionalVectorSpace $ getFractional v1 + getFractional v2
v ^* a = FractionalVectorSpace $ getFractional v * a
zeroVector = FractionalVectorSpace 0
instance Fractional a => VectorSpace (FractionalVectorSpace a) where
instance Num a => InnerProductSpace (FractionalVectorSpace a) where
v1 `dot` v2 = getFractional v1 * getFractional v2
instance Floating a => NormedSpace (FractionalVectorSpace a) where