vector-space 0.3.1 → 0.4
raw patch · 9 files changed
+424/−126 lines, 9 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Data.AdditiveGroup: instance (AdditiveGroup v) => AdditiveGroup (u -> v)
- Data.Maclaurin: (**^) :: (HasBasis a s, HasTrie (Basis a), VectorSpace c s, VectorSpace s s) => (a :> s) -> (a :> c) -> (a :> c)
- Data.Maclaurin: (<*.>) :: (HasBasis a s, HasTrie (Basis a), InnerSpace b s, VectorSpace s s) => (a :> b) -> (a :> b) -> (a :> s)
- Data.Maclaurin: instance (InnerSpace u s, InnerSpace s s', VectorSpace s s, HasBasis a s, HasTrie (Basis a)) => InnerSpace (a :> u) (a :> s)
- Data.VectorSpace: instance (HasTrie u, VectorSpace v s, AdditiveGroup (u :->: v)) => VectorSpace (u :->: v) s
+ Data.ABasis: basisValue :: (HasBasis v) => Basis v -> v
+ Data.ABasis: class (VectorSpace v) => HasBasis v where { type family Basis v :: *; }
+ Data.ABasis: decompose :: (HasBasis v) => v -> [(Basis v, Scalar v)]
+ Data.ABasis: decompose' :: (HasBasis v) => v -> (Basis v -> Scalar v)
+ Data.ABasis: instance (Eq a, HasBasis u) => HasBasis (a -> u)
+ Data.ABasis: instance (s ~ Scalar u, s ~ Scalar v, HasBasis u, HasBasis v) => HasBasis (u, v)
+ Data.ABasis: instance (s ~ Scalar u, s ~ Scalar v, s ~ Scalar w, HasBasis u, HasBasis v, HasBasis w) => HasBasis (u, v, w)
+ Data.ABasis: instance HasBasis Double
+ Data.ABasis: instance HasBasis Float
+ Data.ABasis: linearCombo :: (VectorSpace v) => [(v, Scalar v)] -> v
+ Data.ABasis: recompose :: (HasBasis v) => [(Basis v, Scalar v)] -> v
+ Data.ALinearMap: lapply :: (VectorSpace u, VectorSpace v, (Scalar u) ~ (Scalar v), HasBasis u, HasTrie (Basis u)) => (u :-* v) -> (u -> v)
+ Data.ALinearMap: linear :: (VectorSpace u, VectorSpace v, HasBasis u, HasTrie (Basis u)) => (u -> v) -> (u :-* v)
+ Data.ALinearMap: type :-* u v = Basis u :->: v
+ Data.AVectorSpace: (*^) :: (VectorSpace v) => Scalar v -> v -> v
+ Data.AVectorSpace: (<.>) :: (InnerSpace v) => v -> v -> Scalar v
+ Data.AVectorSpace: (^*) :: (VectorSpace v, s ~ (Scalar v)) => v -> s -> v
+ Data.AVectorSpace: (^/) :: (VectorSpace v, s ~ (Scalar v), Fractional s) => v -> s -> v
+ Data.AVectorSpace: class (VectorSpace v) => InnerSpace v
+ Data.AVectorSpace: class (AdditiveGroup v) => VectorSpace v where { type family Scalar v :: *; }
+ Data.AVectorSpace: instance (HasTrie a, VectorSpace v) => VectorSpace (a :->: v)
+ Data.AVectorSpace: instance (RealFloat v, VectorSpace v) => VectorSpace (Complex v)
+ Data.AVectorSpace: instance (VectorSpace v) => VectorSpace (a -> v)
+ Data.AVectorSpace: instance (s ~ Scalar u, s ~ Scalar v, InnerSpace u, InnerSpace v, AdditiveGroup (Scalar v)) => InnerSpace (u, v)
+ Data.AVectorSpace: instance (s ~ Scalar u, s ~ Scalar v, VectorSpace u, VectorSpace v) => VectorSpace (u, v)
+ Data.AVectorSpace: instance (s ~ Scalar u, s ~ Scalar v, s ~ Scalar w, InnerSpace u, InnerSpace v, InnerSpace w, AdditiveGroup s) => InnerSpace (u, v, w)
+ Data.AVectorSpace: instance (s ~ Scalar u, s ~ Scalar v, s ~ Scalar w, VectorSpace u, VectorSpace v, VectorSpace w) => VectorSpace (u, v, w)
+ Data.AVectorSpace: instance (s ~ Scalar v, RealFloat v, InnerSpace v, AdditiveGroup s) => InnerSpace (Complex v)
+ Data.AVectorSpace: instance InnerSpace Double
+ Data.AVectorSpace: instance InnerSpace Float
+ Data.AVectorSpace: instance VectorSpace Double
+ Data.AVectorSpace: instance VectorSpace Float
+ Data.AVectorSpace: lerp :: (VectorSpace v, s ~ (Scalar v), Num s) => v -> v -> s -> v
+ Data.AVectorSpace: magnitude :: (InnerSpace v, s ~ (Scalar v), Floating s) => v -> s
+ Data.AVectorSpace: magnitudeSq :: (InnerSpace v, s ~ (Scalar v)) => v -> s
+ Data.AVectorSpace: normalized :: (InnerSpace v, s ~ (Scalar v), Floating s) => v -> v
+ Data.AdditiveGroup: instance (AdditiveGroup v) => AdditiveGroup (a -> v)
+ Data.AdditiveGroup: instance AdditiveGroup ()
+ Data.Basis: decompose' :: (HasBasis v s) => v -> (Basis v -> s)
+ Data.Basis: instance (Eq a, HasBasis u s) => HasBasis (a -> u) s
+ Data.Basis: linearCombo :: (VectorSpace v s) => [(v, s)] -> v
+ Data.Basis: recompose :: (HasBasis v s) => [(Basis v, s)] -> v
+ Data.Maclaurin: fstD :: (HasBasis a s, HasTrie (Basis a), HasBasis b s, HasTrie (Basis b), VectorSpace s s) => (a, b) :~> a
+ Data.Maclaurin: instance (InnerSpace u s, InnerSpace s s, VectorSpace s s, HasBasis a s, HasTrie (Basis a)) => InnerSpace (a :> u) (a :> s)
+ Data.Maclaurin: sndD :: (HasBasis a s, HasTrie (Basis a), HasBasis b s, HasTrie (Basis b), VectorSpace s s) => (a, b) :~> b
+ Data.VectorSpace: instance (HasTrie a, VectorSpace v s) => VectorSpace (a :->: v) s
- Data.Basis: decompose :: (HasBasis v s) => v -> [(s, Basis v)]
+ Data.Basis: decompose :: (HasBasis v s) => v -> [(Basis v, s)]
Files
- src/Data/ABasis.hs +135/−0
- src/Data/ALinearMap.hs +44/−0
- src/Data/AVectorSpace.hs +147/−0
- src/Data/AdditiveGroup.hs +8/−3
- src/Data/Basis.hs +48/−14
- src/Data/LinearMap.hs +2/−17
- src/Data/Maclaurin.hs +20/−70
- src/Data/VectorSpace.hs +4/−6
- vector-space.cabal +16/−16
+ src/Data/ABasis.hs view
@@ -0,0 +1,135 @@+-- WARNING: this module depends on type families working fairly well, and+-- requires ghc version at least 6.9. I didn't find a way to specify that+-- dependency in the .cabal.+-- +{-# LANGUAGE TypeOperators, TypeFamilies, UndecidableInstances+ , FlexibleInstances, MultiParamTypeClasses+ #-}+{-# OPTIONS_GHC -Wall -fno-warn-orphans #-}+----------------------------------------------------------------------+-- |+-- Module : Data.ABasis+-- Copyright : (c) Conal Elliott 2008+-- License : BSD3+-- +-- Maintainer : conal@conal.net+-- Stability : experimental+-- +-- Basis of a vector space, as an associated type+-- This module requires ghc-6.10 or later+----------------------------------------------------------------------++module Data.ABasis (HasBasis(..), linearCombo, recompose) where++-- import Control.Applicative ((<$>))+import Control.Arrow (first)+import Data.Either++import Data.AVectorSpace++class VectorSpace v => HasBasis v where+ -- | Representation of the canonical basis for @v@+ type Basis v :: *+ -- | Interpret basis rep as a vector+ basisValue :: Basis v -> v+ -- | Extract coordinates+ decompose :: v -> [(Basis v, Scalar v)]+ -- | Experimental version. More elegant definitions, and friendly to+ -- infinite-dimensional vector spaces.+ decompose' :: v -> (Basis v -> Scalar v)++-- Defining property: recompose . decompose == id++-- | Linear combination+linearCombo :: VectorSpace v => [(v,Scalar v)] -> v+linearCombo ps = sumV [s *^ v | (v,s) <- ps]++-- Turn a basis decomposition back into a vector.+recompose :: HasBasis v => [(Basis v, Scalar v)] -> v+recompose = linearCombo . fmap (first basisValue)++-- recompose ps = linearCombo (first basisValue <$> ps)+++-- I don't know how to define+-- +-- recompose' :: HasBasis v => (Basis v -> Scalar v) -> v+-- +-- However, I don't seem to use recompose anywhere.+-- I don't even use basisValue or decompose.++instance HasBasis Float where+ type Basis Float = ()+ basisValue () = 1+ decompose s = [((),s)]+ decompose' s = const s++instance HasBasis Double where+ type Basis Double = ()+ basisValue () = 1+ decompose s = [((),s)]+ decompose' s = const s++instance ( HasBasis u, s ~ Scalar u+ , HasBasis v, s ~ Scalar v )+ => HasBasis (u,v) where+ type Basis (u,v) = Basis u `Either` Basis v+ basisValue (Left a) = (basisValue a, zeroV)+ basisValue (Right b) = (zeroV, basisValue b)+ decompose (u,v) = decomp2 Left u ++ decomp2 Right v+ decompose' (u,v) = decompose' u `either` decompose' v+++decomp2 :: HasBasis w => (Basis w -> b) -> w -> [(b, Scalar w)]+decomp2 inject = fmap (first inject) . decompose++instance ( HasBasis u, s ~ Scalar u+ , HasBasis v, s ~ Scalar v+ , HasBasis w, s ~ Scalar w )+ => HasBasis (u,v,w) where+ type Basis (u,v,w) = Basis (u,(v,w))+ basisValue = unnest3 . basisValue+ decompose = decompose . nest3+ decompose' = decompose' . nest3++unnest3 :: (a,(b,c)) -> (a,b,c)+unnest3 (a,(b,c)) = (a,b,c)++nest3 :: (a,b,c) -> (a,(b,c))+nest3 (a,b,c) = (a,(b,c))+++instance (Eq a, HasBasis u) => HasBasis (a -> u) where+ type Basis (a -> u) = (a, Basis u)+ basisValue (a,b) = f+ where f a' | a == a' = bv+ | otherwise = zeroV+ bv = basisValue b+ decompose = error "decompose: not defined on functions"+ decompose' g (a,b) = decompose' (g a) b+++-- Simpler but less efficient:+-- +-- basisValue (a,b) a' | a == a' = basisValue b+-- | otherwise = zeroV++-- Just for pointless perversion points:+-- +-- decompose' g = uncurry (\ a b -> decompose' (g a) b)+-- decompose' g = uncurry (\ a -> decompose' (g a))+-- decompose' g = uncurry (decompose' . g)+-- decompose' = uncurry . fmap decompose'+-- decompose' = (fmap uncurry) (fmap decompose')+++{-++---- Testing++t1 = basisValue () :: Float+t2 = basisValue () :: Double+t3 = basisValue (Right ()) :: (Float,Double)+t4 = basisValue (Right (Left ())) :: (Float,Double,Float)++-}
+ src/Data/ALinearMap.hs view
@@ -0,0 +1,44 @@+{-# LANGUAGE TypeOperators, FlexibleContexts, TypeFamilies #-}+{-# OPTIONS_GHC -Wall -fno-warn-orphans #-}+-- {-# OPTIONS_GHC -funbox-strict-fields #-}+-- {-# OPTIONS_GHC -ddump-simpl-stats -ddump-simpl #-}+----------------------------------------------------------------------+-- |+-- Module : Data.ALinearMap+-- Copyright : (c) Conal Elliott 2008+-- License : BSD3+-- +-- Maintainer : conal@conal.net+-- Stability : experimental+-- +-- Linear maps+-- This version uses ABasis, which requires ghc-6.10 or later.+----------------------------------------------------------------------++module Data.ALinearMap+ ( (:-*) , linear, lapply+ ) where++import Control.Arrow (first)+import Data.Function++import Data.MemoTrie+import Data.AVectorSpace+import Data.ABasis+++-- | Linear map, represented as a memo-trie from basis to values.+type u :-* v = Basis u :->: v++-- TODO: Use a regular function from @Basis u@, but memoize it.++-- | Function (assumed linear) as linear map.+linear :: (VectorSpace u, VectorSpace v, HasBasis u, HasTrie (Basis u)) =>+ (u -> v) -> (u :-* v)+linear f = trie (f . basisValue)++-- | Apply a linear map to a vector.+lapply :: ( VectorSpace u, VectorSpace v, Scalar u ~ Scalar v+ , HasBasis u, HasTrie (Basis u) ) =>+ (u :-* v) -> (u -> v)+lapply lm = linearCombo . fmap (first (untrie lm)) . decompose
+ src/Data/AVectorSpace.hs view
@@ -0,0 +1,147 @@+{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies + , TypeOperators, FlexibleInstances, UndecidableInstances+ , TypeFamilies, FlexibleContexts+ #-}+----------------------------------------------------------------------+-- |+-- Module : Data.AVectorSpace+-- Copyright : (c) Conal Elliott and Andy J Gill 2008+-- License : BSD3+-- +-- Maintainer : conal@conal.net, andygill@ku.edu+-- Stability : experimental+-- +-- Vector spaces+-- +-- This version uses associated types instead of fundeps and+-- requires ghc-6.10 or later+----------------------------------------------------------------------++-- NB: I'm attempting to replace fundeps with associated types. See+-- NewVectorSpace.hs. Ran into trouble with type equality constraints not+-- getting propagated. Manuel Ch is looking into it.+-- +-- Blocking bug: http://hackage.haskell.org/trac/ghc/ticket/2448++module Data.AVectorSpace+ ( module Data.AdditiveGroup+ , VectorSpace(..), (^/), (^*)+ , InnerSpace(..)+ , lerp, magnitudeSq, magnitude, normalized+ ) where++import Data.Complex hiding (magnitude)++import Data.AdditiveGroup+import Data.MemoTrie++infixr 7 *^++-- | Vector space @v@ over a scalar field @s@. Extends 'AdditiveGroup'+-- with scalar multiplication.+class AdditiveGroup v => VectorSpace v where+ type Scalar v :: *+ -- | Scale a vector+ (*^) :: Scalar v -> v -> v++infixr 7 <.>++-- | Adds inner (dot) products.+class VectorSpace v => InnerSpace v where+ -- | Inner/dot product+ (<.>) :: v -> v -> Scalar v++infixr 7 ^/+infixl 7 ^*++-- | Vector divided by scalar+(^/) :: (VectorSpace v, s ~ Scalar v, Fractional s) => v -> s -> v+v ^/ s = (1/s) *^ v++-- | Vector multiplied by scalar+(^*) :: (VectorSpace v, s ~ Scalar v) => v -> s -> v+(^*) = flip (*^)++-- | Linear interpolation between @a@ (when @t==0@) and @b@ (when @t==1@).+lerp :: (VectorSpace v, s ~ Scalar v, Num s) => v -> v -> s -> v+lerp a b t = (1-t)*^a ^+^ t*^b++-- | Square of the length of a vector. Sometimes useful for efficiency.+-- See also 'magnitude'.+magnitudeSq :: (InnerSpace v, s ~ Scalar v) => v -> s+magnitudeSq v = v <.> v++-- | Length of a vector. See also 'magnitudeSq'.+magnitude :: (InnerSpace v, s ~ Scalar v, Floating s) => v -> s+magnitude = sqrt . magnitudeSq++-- | Vector in same direction as given one but with length of one. If+-- given the zero vector, then return it.+normalized :: (InnerSpace v, s ~ Scalar v, Floating s) => v -> v+normalized v = v ^/ magnitude v++instance VectorSpace Double where+ type Scalar Double = Double+ (*^) = (*)+instance InnerSpace Double where (<.>) = (*)++instance VectorSpace Float where+ type Scalar Float = Float+ (*^) = (*)+instance InnerSpace Float where (<.>) = (*)++instance (RealFloat v, VectorSpace v) => VectorSpace (Complex v) where+ type Scalar (Complex v) = Scalar v+ s*^(u :+ v) = s*^u :+ s*^v++instance (RealFloat v, InnerSpace v, s ~ Scalar v, AdditiveGroup s)+ => InnerSpace (Complex v) where+ (u :+ v) <.> (u' :+ v') = (u <.> u') ^+^ (v <.> v')++-- Hm. The 'RealFloat' constraint is unfortunate here. It's due to a+-- questionable decision to place 'RealFloat' into the definition of the+-- 'Complex' /type/, rather than in functions and instances as needed.++-- instance (VectorSpace u,VectorSpace v, s ~ Scalar u, s ~ Scalar v)+-- => VectorSpace (u,v) where+-- type Scalar (u,v) = Scalar u+-- s *^ (u,v) = (s*^u,s*^v)++instance ( VectorSpace u, s ~ Scalar u+ , VectorSpace v, s ~ Scalar v )+ => VectorSpace (u,v) where+ type Scalar (u,v) = Scalar u+ s *^ (u,v) = (s*^u,s*^v)++instance ( InnerSpace u, s ~ Scalar u+ , InnerSpace v, s ~ Scalar v+ , AdditiveGroup (Scalar v) )+ => InnerSpace (u,v) where+ (u,v) <.> (u',v') = (u <.> u') ^+^ (v <.> v')++instance ( VectorSpace u, s ~ Scalar u+ , VectorSpace v, s ~ Scalar v+ , VectorSpace w, s ~ Scalar w )+ => VectorSpace (u,v,w) where+ type Scalar (u,v,w) = Scalar u+ s *^ (u,v,w) = (s*^u,s*^v,s*^w)++instance ( InnerSpace u, s ~ Scalar u+ , InnerSpace v, s ~ Scalar v+ , InnerSpace w, s ~ Scalar w+ , AdditiveGroup s )+ => InnerSpace (u,v,w) where+ (u,v,w) <.> (u',v',w') = u<.>u' ^+^ v<.>v' ^+^ w<.>w'+++-- Standard instance for an applicative functor applied to a vector space.+instance VectorSpace v => VectorSpace (a -> v) where+ type Scalar (a -> v) = Scalar v+ (*^) s = fmap (s *^)++-- No 'InnerSpace' instance for @(a -> v)@.++instance (HasTrie a, VectorSpace v)+ => VectorSpace (a :->: v) where+ type Scalar (a :->: v) = Scalar v+ (*^) s = fmap ((*^) s)
src/Data/AdditiveGroup.hs view
@@ -40,6 +40,11 @@ sumV :: AdditiveGroup v => [v] -> v sumV = foldr (^+^) zeroV +instance AdditiveGroup () where+ zeroV = ()+ () ^+^ () = ()+ negateV = id+ instance AdditiveGroup Double where zeroV = 0.0 (^+^) = (+)@@ -62,17 +67,17 @@ instance (AdditiveGroup u,AdditiveGroup v) => AdditiveGroup (u,v) where zeroV = (zeroV,zeroV) (u,v) ^+^ (u',v') = (u^+^u',v^+^v')- negateV (u,v) = (negateV u, negateV v)+ negateV (u,v) = (negateV u,negateV v) instance (AdditiveGroup u,AdditiveGroup v,AdditiveGroup w) => AdditiveGroup (u,v,w) where zeroV = (zeroV,zeroV,zeroV) (u,v,w) ^+^ (u',v',w') = (u^+^u',v^+^v',w^+^w')- negateV (u,v,w) = (negateV u, negateV v, negateV w)+ negateV (u,v,w) = (negateV u,negateV v,negateV w) -- Standard instance for an applicative functor applied to a vector space.-instance AdditiveGroup v => AdditiveGroup (u->v) where+instance AdditiveGroup v => AdditiveGroup (a -> v) where zeroV = pure zeroV (^+^) = liftA2 (^+^) negateV = fmap negateV
src/Data/Basis.hs view
@@ -15,51 +15,76 @@ -- Maintainer : conal@conal.net -- Stability : experimental -- --- Basis of a vector space, as an associated type+-- Basis of a vector space, as an associated type.+-- This version works with @Data.VectorSpace@, thus avoiding a bug in+-- ghc-6.9.. ---------------------------------------------------------------------- -module Data.Basis- (- HasBasis(..)- ) where+module Data.Basis (HasBasis(..), linearCombo, recompose) where -import Control.Arrow (second)+import Control.Arrow (first) import Data.Either import Data.VectorSpace class VectorSpace v s => HasBasis v s where+ -- | Representation of the canonical basis for @v@ type Basis v :: *- basisValue :: Basis v -> v- decompose :: v -> [(s, Basis v)]+ -- | Interpret basis rep as a vector+ basisValue :: Basis v -> v+ -- | Extract coordinates+ decompose :: v -> [(Basis v, s)]+ -- | Experimental version. More elegant definitions, and friendly to+ -- infinite-dimensional vector spaces.+ decompose' :: v -> (Basis v -> s) --- TODO: switch from fundep to associated type. eliminate the second type+-- TODO: Switch from fundep to associated type. Eliminate the second type -- parameter in VectorSpace and HasBasis. -- Blocking bug: http://hackage.haskell.org/trac/ghc/ticket/2448+-- Fixed in ghc 6.10. +-- Defining property: recompose . decompose == id++-- | Linear combination+linearCombo :: VectorSpace v s => [(v,s)] -> v+linearCombo ps = sumV [s *^ v | (v,s) <- ps]++-- | Turn a basis decomposition back into a vector.+recompose :: HasBasis v s => [(Basis v, s)] -> v+recompose = linearCombo . fmap (first basisValue)++-- recompose ps = linearCombo (first basisValue <$> ps)+++-- recompose = sumV . fmap (\ (b,s) -> s *^ basisValue b)+ instance HasBasis Float Float where type Basis Float = () basisValue () = 1- decompose s = [(s,())]+ decompose s = [((),s)]+ decompose' s = const s instance HasBasis Double Double where type Basis Double = () basisValue () = 1- decompose s = [(s,())]+ decompose s = [((),s)]+ decompose' s = const s instance (HasBasis u s, HasBasis v s) => HasBasis (u,v) s where type Basis (u,v) = Basis u `Either` Basis v basisValue (Left a) = (basisValue a, zeroV) basisValue (Right b) = (zeroV, basisValue b)- decompose (u,v) = decomp2 Left u ++ decomp2 Right v+ decompose (u,v) = decomp2 Left u ++ decomp2 Right v+ decompose' (u,v) = decompose' u `either` decompose' v -decomp2 :: HasBasis w s => (Basis w -> b) -> w -> [(s, b)]-decomp2 inject = fmap (second inject) . decompose+decomp2 :: HasBasis w s => (Basis w -> b) -> w -> [(b, s)]+decomp2 inject = fmap (first inject) . decompose instance (HasBasis u s, HasBasis v s, HasBasis w s) => HasBasis (u,v,w) s where type Basis (u,v,w) = Basis (u,(v,w)) basisValue = unnest3 . basisValue decompose = decompose . nest3+ decompose' = decompose' . nest3 unnest3 :: (a,(b,c)) -> (a,b,c) unnest3 (a,(b,c)) = (a,b,c)@@ -79,6 +104,15 @@ -- -- type Basis (u,v,w) = Basis u `Either` Basis (v,w) ++instance (Eq a, HasBasis u s) => HasBasis (a -> u) s where+ type Basis (a -> u) = (a, Basis u)+ basisValue (a,b) = f+ where f a' | a == a' = bv+ | otherwise = zeroV+ bv = basisValue b+ decompose = error "decompose: not defined on functions"+ decompose' g (a,b) = decompose' (g a) b {-
src/Data/LinearMap.hs view
@@ -16,18 +16,15 @@ module Data.LinearMap ( (:-*) , linear, lapply- -- , inL, inL2, inL3 ) where --- -fglasgow-exts above enables the RULES pragma-+import Control.Arrow (first) import Data.Function import Data.VectorSpace import Data.MemoTrie import Data.Basis - -- | Linear map, represented a as a memo function from basis to values. type u :-* v = Basis u :->: v @@ -39,20 +36,8 @@ -- | Apply a linear map to a vector. lapply :: (VectorSpace u s, VectorSpace v s, HasBasis u s, HasTrie (Basis u)) => (u :-* v) -> (u -> v)-lapply lm u = sumV [s *^ (lm `untrie` b) | (s,b) <- decompose u]+lapply lm = linearCombo . fmap (first (untrie lm)) . decompose -- TODO: unfst, unsnd, pair, unpair ------ OpenGL stuff.---- I'd rather this code be in a different package. It's here as a--- temporary bug workaround. In ghc-6.8.2, I get the following error--- message if the 'LMapDom' instance (below) is compiled in a separate--- module.--- --- Type indexes must match class instance head --- Found o but expected Vector2 u --- In the associated type instance for `:-*' --- In the instance declaration for `LMapDom (Vector2 u) s'
src/Data/Maclaurin.hs view
@@ -33,14 +33,10 @@ (:>), powVal, derivative --, derivativeAt , (:~>), dZero, pureD , fmapD, (<$>>){-, (<*>>)-}, liftD2, liftD3- , idD -- , fstD, sndD+ , idD, fstD, sndD , linearD, distrib -- , (@.) , (>-<)- ,(**^), (<*.>)- -- , HasDeriv(..)- -- experimental- -- , liftD3 ) where @@ -127,7 +123,7 @@ -- | Every linear function has a constant derivative equal to the function -- itself (as a linear map).-linearD :: ( HasBasis u s, HasTrie (Basis u){-, VectorSpace (u :> v) s, -}+linearD :: ( HasBasis u s, HasTrie (Basis u) , VectorSpace v s, VectorSpace s s ) => (u -> v) -> (u :~> v) @@ -166,64 +162,41 @@ -- TODO: revise two previous signatures when i've added the VectorSpace instance for u:>v -{-- -- Other examples of linear functions -- | Differentiable version of 'fst'-fstD :: -- (VectorSpace a s, HasBasis a s, HasTrie (Basis a), HasBasis b s, HasTrie (Basis b)) =>- ( HasBasis a s, HasTrie (Basis a)+fstD :: ( HasBasis a s, HasTrie (Basis a) , HasBasis b s, HasTrie (Basis b)- , HasBasis (a,b) s, HasTrie (Basis (a, b))- ) =>- (a,b) :~> a+ , VectorSpace s s+ ) => (a,b) :~> a fstD = linearD fst --- wtf:--- --- Data/NewMaclaurin.hs:138:7:--- Could not deduce (HasTrie (Basis (a, b)))--- from the context (HasBasis a s,--- HasTrie (Basis a),--- HasBasis b s,--- HasTrie (Basis b),--- HasBasis (a, b) s,--- HasTrie (Basis (a, b)))--- arising from a use of `linearD' at Data/NewMaclaurin.hs:138:7-17--- Possible fix:--- add (HasTrie (Basis (a, b))) to the context of--- the type signature for `fstD'--- or add an instance declaration for (HasTrie (Basis (a, b)))--- In the expression: linearD fst--- In the definition of `fstD': fstD = linearD fst--- Failed, modules loaded: Data.MemoTrie, Data.Basis, Data.VectorSpace, Data.AdditiveGroup, Data.NumInstances.--- *Data.Basis> ---- -- | Differentiable version of 'snd'--- sndD :: (VectorSpace b s, HasBasis b s, HasTrie (Basis b), HasTrie (Basis a)) => (a,b) :~> b--- sndD = linearD snd---}+-- | Differentiable version of 'snd'+sndD :: ( HasBasis a s, HasTrie (Basis a)+ , HasBasis b s, HasTrie (Basis b)+ , VectorSpace s s+ ) => (a,b) :~> b+sndD = linearD snd -- | Derivative tower for applying a binary function that distributes over -- addition, such as multiplication. A bit weaker assumption than -- bilinearity. distrib :: ( HasBasis a s, HasTrie (Basis a)- , VectorSpace b s, VectorSpace c s, VectorSpace u s) =>- (b -> c -> u) -> (a :> b) -> (a :> c) -> (a :> u)+ , VectorSpace b s, VectorSpace c s, VectorSpace u s+ ) => (b -> c -> u) -> (a :> b) -> (a :> c) -> (a :> u) distrib op u@(D u0 u') v@(D v0 v') = D (u0 `op` v0) (trie (\ da -> distrib op u (v' `untrie` da) ^+^ distrib op (u' `untrie` da) v)) --- TODO: look for a simpler definition of distrib. See inTrie2. +-- TODO: look for a simpler definition of distrib. See the applicative+-- instance for @(:->:) a@, or define @inTrie2@.+ -- TODO: This distrib is exponential in increasing degree. Switch to the -- Horner representation. See /The Music of Streams/ by Doug McIlroy. --- I'm not sure about the next three, which discard information- instance Show b => Show (a :> b) where show = noOv "show" instance Eq b => Eq (a :> b) where (==) = noOv "(==)" instance Ord b => Ord (a :> b) where compare = noOv "compare"@@ -233,37 +206,14 @@ negateV = fmapD negateV (^+^) = liftD2 (^+^) -{--instance (HasBasis a s, HasTrie (Basis a), VectorSpace u s) => VectorSpace (a :> u) s where- (*^) s = fmapD ((*^) s)--}--(**^) :: (HasBasis a s, HasTrie (Basis a), VectorSpace c s, VectorSpace s s) =>- (a :> s) -> (a :> c) -> (a :> c)-(**^) = distrib (*^)---- ouch! InnerSpace one won't work at all, for the same reason as for functions.---- instance (InnerSpace u s) => InnerSpace (a :> u) s where--- (<.>) = distrib (<.>)--(<*.>) :: (HasBasis a s, HasTrie (Basis a), InnerSpace b s, VectorSpace s s) =>- (a :> b) -> (a :> b) -> (a :> s)-(<*.>) = distrib (<.>)----- The instances below are the one I think we'll want externally.--- However, the ones above allow the definition of @a:>b@ to work out.--- The module "Data.Mac" rewraps to provide the alternate instances.- instance (HasBasis a s, HasTrie (Basis a), VectorSpace u s, VectorSpace s s) => VectorSpace (a :> u) (a :> s) where- (*^) = (**^)+ (*^) = distrib (*^) -instance ( InnerSpace u s, InnerSpace s s', VectorSpace s s+instance ( InnerSpace u s, InnerSpace s s, VectorSpace s s , HasBasis a s, HasTrie (Basis a)) => InnerSpace (a :> u) (a :> s) where- (<.>) = (<*.>)+ (<.>) = distrib (<.>) -- infixr 9 @.@@ -281,7 +231,7 @@ (>-<) :: (HasBasis a s, HasTrie (Basis a), VectorSpace s s, VectorSpace u s) => (u -> u) -> ((a :> u) -> (a :> s)) -> (a :> u) -> (a :> u)-f >-< f' = \ u@(D u0 u') -> D (f u0) ((f' u **^) <$> u')+f >-< f' = \ u@(D u0 u') -> D (f u0) (f' u *^ u') -- TODO: express '(>-<)' in terms of '(@.)'. If I can't, then understand why not.
src/Data/VectorSpace.hs view
@@ -10,7 +10,8 @@ -- Maintainer : conal@conal.net, andygill@ku.edu -- Stability : experimental -- --- Vector spaces+-- Vector spaces. Fundep version. GHC-6.9 isn't quite up to the nicer+-- version in @Data.VectorSpace@, which uses associated types. ---------------------------------------------------------------------- -- NB: I'm attempting to replace fundeps with associated types. See@@ -111,9 +112,6 @@ -- No 'InnerSpace' instance for @(a->v)@. -instance (HasTrie u, VectorSpace v s, AdditiveGroup (u :->: v))- => VectorSpace (u :->: v) s where+instance (HasTrie a, VectorSpace v s)+ => VectorSpace (a :->: v) s where (*^) s = fmap (s *^)---- The 'AdditiveGroup' constraint is implied by the others, thanks to the--- instance in Data.AdditiveGroup. Why isn't ghc figuring it out?
vector-space.cabal view
@@ -1,5 +1,5 @@ Name: vector-space-Version: 0.3.1+Version: 0.4 Cabal-Version: >= 1.2 Synopsis: Vector & affine spaces, linear maps, and derivatives (requires ghc 6.9) Category: math@@ -28,35 +28,35 @@ Stability: experimental build-type: Simple --- WARNING: Data.Basis depends on type families working fairly well,--- and requires ghc version at least 6.9. I don't know how to specify--- that dependency in the .cabal.- Library hs-Source-Dirs: src Extensions: Build-Depends: base, MemoTrie Exposed-Modules: - Data.AdditiveGroup Data.VectorSpace Data.Basis Data.LinearMap Data.Maclaurin+-- Data.Horner Data.Derivative Data.Cross Data.AffineSpace Data.NumInstances+ + -- This library relies on type families working as well as in 6.9.+ if impl(ghc < 6.9) {+ buildable: False+ }+ -- More bug fixes in 6.10 allow replacing some fundeps. After a while,+ -- when 6.10 is widespread, I'll switch over entirely and eliminate the+ -- earlier versions.+ if impl(ghc >= 6.10) {+ Exposed-Modules:+ Data.AVectorSpace+ Data.ABasis+ Data.ALinearMap+ } ghc-options: -Wall -O2 ghc-prof-options: -prof -auto-all --- -fno-method-sharing---- Executable Perf--- main-is: Perf.hs--- build-depends: base, OpenGL, old-time--- Hs-Source-Dirs: src, tests/src--- ghc-options: -Wall -O2--- ghc-prof-options: -prof -auto-all ---- Data.Horner -- For ghc-options: -ddump-simpl-stats -ddump-rules -ddump-simpl -ddump-simpl-phases