goal-geometry-0.1: Goal/Geometry/Linear.hs
-- | The 'Linear' module provides the tools for treating a given 'Manifold' as a
-- linear space.
module Goal.Geometry.Linear (
-- * Vector Spaces
(<+>)
, (.>)
, (<->)
, (/>)
, meanPoint
-- * Dual Spaces
, Primal
, Dual
, (<.>)
) where
--- Imports ---
import Prelude hiding (map,minimum,maximum)
-- Package --
import Goal.Core hiding (dot)
import Goal.Geometry.Manifold
-- Unqualified --
import Numeric.LinearAlgebra.HMatrix hiding (Field,(><),(<>),(<.>))
--import Data.Vector.Storable.UnsafeSerialize
--- Vector Spaces on Manifolds ---
infixl 6 <+>
(<+>) :: Manifold m => c :#: m -> c :#: m -> c :#: m
-- | Vector addition of points on a manifold.
(<+>) p p' = fromCoordinates (manifold p) (coordinates p' + coordinates p)
{-
| m == manifold p' = fromCoordinates m (coordinates p' + coordinates p)
| otherwise = error "Attempting to add points from distinct manifolds."
where m = manifold p
-}
infixl 6 <->
(<->) :: Manifold m => c :#: m -> c :#: m -> c :#: m
-- | Vector subtraction of points on a manifold.
(<->) p p' = fromCoordinates (manifold p) (coordinates p - coordinates p')
{-
| m == manifold p' = fromCoordinates m (coordinates p - coordinates p')
| otherwise = error "Attempting to subtract points from distinct manifolds."
where m = manifold p
-}
infix 7 .>
(.>) :: Manifold m => Double -> c :#: m -> c :#: m
-- | Scalar multiplication of points on a manifold.
(.>) a = alterCoordinates (*a)
infix 7 />
(/>) :: Manifold m => Double -> c :#: m -> c :#: m
-- | Scalar division of points on a manifold.
(/>) a v = recip a .> v
--- Dual Spaces ---
-- | 'Primal' charts have a 'Dual' coordinate system. The 'Dual' coordinate
-- system is the system which determines the dual basis of the dual vector
-- space via the restriction that the inner product '<.>' be the dot product.
--
-- Since finite dimensional vector spaces are isomorphic to their dual spaces
-- through the dual basis, vector space duality is handled purely at the level
-- of coordinates in Goal -- that is, 'Primal' and 'Dual' coordinates are
-- considered different ways of describing the same fundamental objects. In
-- practice, encoding this relationship purely at the level of Charts saves a
-- great deal of computational effort.
class (Dual (Dual c)) ~ c => Primal c where
type Dual c :: *
infix 7 <.>
(<.>) :: c :#: m -> Dual c :#: m -> Double
-- | '<.>' is the inner product between a dual pair of 'Point's. The defining
-- property of 'Dual' coordinate systems is that the inner product can be
-- expressed as a dot product.
(<.>) p q = dot (coordinates p) (coordinates q)
-- Utility --
meanPoint :: Manifold m => [c :#: m] -> c :#: m
-- | Finds the midpoint amongst a set of vectors in a convex set.
meanPoint ps = fromCoordinates (manifold $ head ps) . mean $ coordinates <$> ps
{-
| all (== m) (manifold <$> ps) = fromCoordinates m . mean $ coordinates <$> ps
| otherwise = error "Attempting to add points from distinct manifolds."
where m = manifold $ head ps
-}
--- Instances ---
-- Cartesian Spaces --
instance Primal Cartesian where
type Dual Cartesian = Cartesian