Vec 0.9.0 → 0.9.1
raw patch · 4 files changed
+155/−22 lines, 4 files
Files
- Data/Vec/Instances.hs +3/−0
- Data/Vec/LinAlg.hs +9/−11
- Data/Vec/Packed.hs +141/−9
- Vec.cabal +2/−2
Data/Vec/Instances.hs view
@@ -1,4 +1,5 @@ {- Copyright (c) 2008, Scott E. Dillard. All rights reserved. -}+{-# OPTIONS -cpp #-} {-# LANGUAGE BangPatterns #-} {-# LANGUAGE EmptyDataDecls #-}@@ -15,6 +16,7 @@ module Data.Vec.Instances where +import Prelude hiding (map,foldl,foldr,zipWith) import Data.Vec.Base as V import Data.Vec.Nat import Foreign.Storable@@ -115,3 +117,4 @@ {-# INLINE (/) #-} {-# INLINE recip #-} {-# INLINE fromRational #-}+
Data/Vec/LinAlg.hs view
@@ -37,7 +37,7 @@ ,scale ,diagonal ,identity- ,Det(det)+ ,det ,cramer'sRule ,NearZero(nearZero) ,GaussElim(gaussElim)@@ -395,15 +395,13 @@ -- enforce that here. But really I have no clue. -class Det n a m | m -> a where- -- | Determinant by minor expansion. Unfolds into a closed form expression.- -- This should be the fastest way for 4x4 and smaller, but @snd . gaussElim@- -- works too.- det :: m -> a+-- | Determinant by minor expansion. Unfolds into a closed form expression.+-- This should be the fastest way for 4x4 and smaller, but @snd . gaussElim@+-- works too. -instance (Vec n a r, Vec n r m, Det' a m) => Det n a m where- det = det'- {-# INLINE det #-}+det :: forall n a r m. (Vec n a r, Vec n r m, Det' a m) => m -> a+det = det'+{-# INLINE det #-} @@ -502,9 +500,10 @@ -- first row. Does not try to find the 'best' pivot, only an acceptable one: -- matrices are assumed small, roundoff error should be negligible. -class Pivot1 a m | m -> a where+class Pivot1 a m where pivot1 :: m -> Maybe (m,a) +--this instance prevents a fundep inferring type of a from m. instance Pivot1 a () where pivot1 _ = Nothing @@ -704,7 +703,6 @@ where dropn = drop (undefined::n) i = identity :: m {-# INLINE invertAndDet #-}- -- | Solution of linear system by Gaussian elimination. Returns @Nothing@ -- if no solution.
Data/Vec/Packed.hs view
@@ -1,5 +1,7 @@ {- Copyright (c) 2008, Scott E. Dillard. All rights reserved. -}+{-# OPTIONS -cpp #-} + {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE MultiParamTypeClasses #-}@@ -11,50 +13,90 @@ -- | Packed vectors : use these whenever possible. The regular vector type is -- just a gussied up linked list, but when vector functions are applied to -- these types, bracketed by @'pack'@ and @'unpack'@, then things unfold into--- perfectly optimized code.+-- neatly optimized code. +-- +-- Storable, Num, Fractional, Fold, Map, and ZipWith instances are provided for+-- packed vectors, so some operations do not require pack/unpack. For example,+-- @'dot'@ does not require pack/unpack because it is defined in terms of+-- @'zipWith'@ and @'fold'@. However @'transpose'@, @'det'@, @'gaussElim'@ and+-- most others are recursive, and so you'll still need to use pack/unpack with+-- these. This goes for @'multmm'@ as well because it uses @'transpose'@, and+-- @'multmv'@ does not need its arguments to be unpacked, but the result will+-- be a polymorphic vector of type @(:.)@, so you will want to pack it again.+-- This is all very experimental and likely to change. module Data.Vec.Packed where +import Prelude hiding (map,foldl,foldr,zipWith) import Data.Vec.Base as V+import Data.Vec.Instances+import Foreign +-- | PackedVec class : relates a packed vector type to its unpacked type For+-- now, the fundep is not bijective -- It may be advantageous to have multiple+-- packed representations for a canonical vector type. This may change. In the+-- meantime, you may have to annotate return types.+class PackedVec pv v | pv -> v where+ pack :: v -> pv+ unpack :: pv -> v++{-# RULES + "Vec pack/unpack" forall x.+ pack (unpack x) = x;+ "Vec unpack/pack" forall x.+ unpack (pack x) = x;+ "Vec pack.unpack" + pack . unpack = id;+ "Vec unpack.pack"+ unpack . pack = id; #-}+ -- * Packed Vector Types data Vec2I = Vec2I {-#UNPACK#-} !Int {-#UNPACK#-} !Int + deriving (Eq,Ord,Show,Read) data Vec3I = Vec3I {-#UNPACK#-} !Int {-#UNPACK#-} !Int {-#UNPACK#-} !Int+ deriving (Eq,Ord,Show,Read) data Vec4I = Vec4I {-#UNPACK#-} !Int {-#UNPACK#-} !Int {-#UNPACK#-} !Int {-#UNPACK#-} !Int+ deriving (Eq,Ord,Show,Read) data Vec2F = Vec2F {-#UNPACK#-} !Float {-#UNPACK#-} !Float + deriving (Eq,Ord,Show,Read) data Vec3F = Vec3F {-#UNPACK#-} !Float {-#UNPACK#-} !Float {-#UNPACK#-} !Float+ deriving (Eq,Ord,Show,Read) data Vec4F = Vec4F {-#UNPACK#-} !Float {-#UNPACK#-} !Float {-#UNPACK#-} !Float {-#UNPACK#-} !Float+ deriving (Eq,Ord,Show,Read) data Vec2D = Vec2D {-#UNPACK#-} !Double {-#UNPACK#-} !Double + deriving (Eq,Ord,Show,Read) data Vec3D = Vec3D {-#UNPACK#-} !Double {-#UNPACK#-} !Double {-#UNPACK#-} !Double+ deriving (Eq,Ord,Show,Read) data Vec4D = Vec4D {-#UNPACK#-} !Double {-#UNPACK#-} !Double {-#UNPACK#-} !Double {-#UNPACK#-} !Double+ deriving (Eq,Ord,Show,Read) --- * Packed Matrix Types. +-- * Packed Matrix Types type Mat22I = Vec2 Vec2I type Mat23I = Vec2 Vec3I type Mat33I = Vec3 Vec3I @@ -84,13 +126,6 @@ unpackMat = V.map unpack {-# INLINE unpackMat #-} --- | PackedVec class : relates a packed vector type to its unpacked type For--- now, the fundep is not bijective -- It may be advantageous to have multiple--- packed representations for a canonical vector type. This may change. In the--- meantime, you may have to annotate return types.-class PackedVec pv v | pv -> v where- pack :: v -> pv- unpack :: pv -> v instance PackedVec Vec2I (Vec2 Int) where pack (x:.y:.()) = Vec2I x y @@ -148,5 +183,102 @@ {-# INLINE pack #-} {-# INLINE unpack #-} +#define MAP_INSTANCE(S,V) \+instance Map S S V V where map f = pack . map f . unpack +MAP_INSTANCE(Int,Vec2I)+MAP_INSTANCE(Int,Vec3I)+MAP_INSTANCE(Int,Vec4I)+MAP_INSTANCE(Float,Vec2F)+MAP_INSTANCE(Float,Vec3F)+MAP_INSTANCE(Float,Vec4F)+MAP_INSTANCE(Double,Vec2D)+MAP_INSTANCE(Double,Vec3D)+MAP_INSTANCE(Double,Vec4D)+++#define FOLD_INSTANCE(S,V) \+instance Fold S V where \+ fold f = fold f . unpack; \+ foldl f z = foldl f z . unpack; \+ foldr f z = foldr f z . unpack;++FOLD_INSTANCE(Int,Vec2I)+FOLD_INSTANCE(Int,Vec3I)+FOLD_INSTANCE(Int,Vec4I)+FOLD_INSTANCE(Float,Vec2F)+FOLD_INSTANCE(Float,Vec3F)+FOLD_INSTANCE(Float,Vec4F)+FOLD_INSTANCE(Double,Vec2D)+FOLD_INSTANCE(Double,Vec3D)+FOLD_INSTANCE(Double,Vec4D)++#define ZIPWITH_INSTANCE(S,V) \+instance ZipWith S S S V V V where \+ zipWith f u v = pack $ zipWith f (unpack u) (unpack v)++ZIPWITH_INSTANCE(Int,Vec2I)+ZIPWITH_INSTANCE(Int,Vec3I)+ZIPWITH_INSTANCE(Int,Vec4I)+ZIPWITH_INSTANCE(Float,Vec2F)+ZIPWITH_INSTANCE(Float,Vec3F)+ZIPWITH_INSTANCE(Float,Vec4F)+ZIPWITH_INSTANCE(Double,Vec2D)+ZIPWITH_INSTANCE(Double,Vec3D)+ZIPWITH_INSTANCE(Double,Vec4D)+++#define NUM_INSTANCE(V) \+instance Num V where \+ u + v = pack $ unpack u + unpack v ; \+ u - v = pack $ unpack u + unpack v ; \+ u * v = pack $ unpack u * unpack v ; \+ abs = pack . abs . unpack ; \+ signum = pack . signum . unpack ; \+ fromInteger = pack . fromInteger++NUM_INSTANCE(Vec2I)+NUM_INSTANCE(Vec3I)+NUM_INSTANCE(Vec4I)+NUM_INSTANCE(Vec2F)+NUM_INSTANCE(Vec3F)+NUM_INSTANCE(Vec4F)+NUM_INSTANCE(Vec2D)+NUM_INSTANCE(Vec3D)+NUM_INSTANCE(Vec4D)++#define FRACTIONAL_INSTANCE(V) \+instance Fractional V where \+ u / v = pack $ unpack u / unpack v ;\+ recip = pack . recip . unpack ;\+ fromRational = pack . fromRational++FRACTIONAL_INSTANCE(Vec2F)+FRACTIONAL_INSTANCE(Vec3F)+FRACTIONAL_INSTANCE(Vec4F)+FRACTIONAL_INSTANCE(Vec2D)+FRACTIONAL_INSTANCE(Vec3D)+FRACTIONAL_INSTANCE(Vec4D)+++#define STORABLE_INSTANCE(V,PV) \+instance Storable PV where \+ sizeOf = sizeOf.unpack ;\+ alignment = alignment.unpack ;\+ peek p = peek (castPtr p) >>= return.pack ;\+ poke p v = poke (castPtr p) (unpack v) ;\+ peekElemOff p i = peekElemOff (castPtr p) i >>= return.pack ;\+ pokeElemOff p i v = pokeElemOff (castPtr p) i (unpack v) ;\+ peekByteOff p b = peekByteOff (castPtr p) b >>= return.pack ;\+ pokeByteOff p b v = pokeByteOff (castPtr p) b (unpack v) ;\++STORABLE_INSTANCE(Vec2 Int,Vec2I)+STORABLE_INSTANCE(Vec3 Int,Vec3I)+STORABLE_INSTANCE(Vec4 Int,Vec4I)+STORABLE_INSTANCE(Vec2 Float,Vec2F)+STORABLE_INSTANCE(Vec3 Float,Vec3F)+STORABLE_INSTANCE(Vec4 Float,Vec4F)+STORABLE_INSTANCE(Vec2 Double,Vec2D)+STORABLE_INSTANCE(Vec3 Double,Vec3D)+STORABLE_INSTANCE(Vec4 Double,Vec4D)
Vec.cabal view
@@ -1,5 +1,5 @@ Name: Vec-Version: 0.9.0+Version: 0.9.1 License: BSD3 License-file: LICENSE Author: Scott E. Dillard@@ -16,7 +16,7 @@ linear systems, inverting matrices. Cabal-version: >=1.2 Build-type: Simple-Category: Math,Graphics+Category: Data,Math library Build-Depends: base