packages feed

Vec 0.9.2 → 0.9.3

raw patch · 5 files changed

+105/−176 lines, 5 filesdep ~QuickCheck

Dependency ranges changed: QuickCheck

Files

Data/Vec/Base.hs view
@@ -1,8 +1,6 @@ {- Copyright (c) 2008, Scott E. Dillard. All rights reserved. -} -{-# LANGUAGE BangPatterns #-} {-# LANGUAGE EmptyDataDecls #-}-{-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FunctionalDependencies #-}@@ -13,7 +11,7 @@ {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE UndecidableInstances #-} -{-# HADDOCK_OPTIONS prune #-}+-- {-# HADDOCK_OPTIONS prune #-}  module Data.Vec.Base where @@ -85,57 +83,77 @@   -- Use `vec` when the length can be inferred.   mkVec :: n -> a -> v -  -- | turn a list into a vector of inferred length++instance Vec N1 a ( a :. () ) where+  mkVec _ a = a :. ()+  {-# INLINE mkVec #-}++instance Vec (Succ n) a (a':.v) => Vec (Succ (Succ n)) a (a:.a':.v) where+  mkVec _ a = a :. (mkVec undefined a)+  {-# INLINE mkVec #-}+++-- | Make a uniform vector. The length is inferred.+vec ::  (Vec n a v) => a -> v+vec = mkVec undefined+{-# INLINE vec #-}+++-- | Build a vector from a list, or access vector elements using run-time+-- indicies, numbered from 0.++class VecList a v | v -> a where+  -- | Turn a list into a vector of inferred length. The list must be at least+  -- as long as the vector, but may be longer. Make a mental note of the+  -- distinction between this and 'matFromList', as you might accidentally use+  -- this when you mean that. Because number literals can be converted to+  -- vectors, and matrices are vectors of vectors, the following works+  -- +  -- > fromList [1,2,3,4] :: 'Mat22' Int +  -- > > ((1):.(1):.()):.((2):.(2):.()):.()+  --+  -- even though we meant to do this+  --+  -- > 'matFromList' [1,2,3,4] :: 'Mat22' Int +  -- > > ((1):.(2):.()):.((3):.(4):.()):.()   fromList :: [a] -> v -  -- | get a vector element, which one is determined at runtime+  -- | Get a vector element, which one determined at runtime.   getElem :: Int -> v -> a -  -- | set a vector element, which one is determined at runtime+  -- | Set a vector element, which one determined at runtime   setElem :: Int -> a -> v -> v -instance Vec N1 a ( a :. () ) where-  mkVec _ a = a :. ()+instance VecList a (a:.()) where   fromList (a:_)   = a :. ()   fromList []      = error "fromList: list too short"-  getElem !i (a :. _) +  getElem i (a :. _)     | i == 0    = a     | otherwise = error "getElem: index out of bounds"-  setElem !i a _ +  setElem i a _      | i == 0    = a :. ()     | otherwise = error "setElem: index out of bounds"   {-# INLINE setElem #-}   {-# INLINE getElem #-}-  {-# INLINE mkVec #-}   {-# INLINE fromList #-} -instance Vec (Succ n) a (a':.v) => Vec (Succ (Succ n)) a (a:.a':.v) where-  mkVec _ a = a :. (mkVec undefined a)-  fromList (a:as)  = a :. (fromList as)+instance VecList a (a':.v) => VecList a (a:.(a':.v)) where+  fromList (a:as)  = a :. fromList as   fromList []      = error "fromList: list too short"-  getElem !i (a :. v)+  getElem i (a :. v)     | i == 0    = a     | otherwise = getElem (i-1) v-  setElem !i a (x :. v)-    | i == 0    = a :. v-    | otherwise = x :. (setElem (i-1) a v)+  setElem i a' (a :. v)+    | i == 0    = a' :. v+    | otherwise = a :. (setElem (i-1) a' v)   {-# INLINE setElem #-}   {-# INLINE getElem #-}-  {-# INLINE mkVec #-}   {-# INLINE fromList #-} ---- | Make a uniform vector. The length is inferred.-vec ::  (Vec n a v) => a -> v-vec = mkVec undefined-{-# INLINE vec #-}-- -- | get or set a vector element, known at compile --time. Use the Nat types to access vector components. For instance, @get n0@ --gets the x component, @set n2 44@ sets the z component to 44.  - class Access n a v | v -> a where   get  :: n -> v -> a   set  :: n -> a -> v -> v@@ -418,12 +436,12 @@ {-# INLINE matToList    #-}  -- | convert a list-of-lists into a matrix-matFromLists :: (Vec j a v, Vec i v m) => [[a]] -> m+matFromLists :: (Vec j a v, Vec i v m, VecList a v, VecList v m) => [[a]] -> m matFromLists = fromList . (P.map fromList) {-# INLINE matFromLists #-}  -- | convert a list into a matrix. (row-major order)-matFromList :: forall i j v m a. (Vec i v m, Vec j a v, Nat i) => [a] -> m+matFromList :: forall i j v m a. (Vec i v m, Vec j a v, Nat i, VecList a v, VecList v m) => [a] -> m matFromList  = matFromLists . groupsOf (nat(undefined::i))   where groupsOf n xs = let (a,b) = splitAt n xs in a:(groupsOf n b) {-# INLINE matFromList  #-}
− Data/Vec/Instances.hs
@@ -1,132 +0,0 @@-{- Copyright (c) 2008, Scott E. Dillard. All rights reserved. -}-{-# OPTIONS -cpp #-}--{-# LANGUAGE EmptyDataDecls #-}-{-# LANGUAGE ExistentialQuantification #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE NoMonomorphismRestriction #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE TypeSynonymInstances #-}-{-# LANGUAGE UndecidableInstances #-}--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-import Foreign.Ptr-import Test.QuickCheck---- Storable instances. --instance Storable a => Storable (a:.()) where-  sizeOf _ = sizeOf (undefined::a)-  alignment _ = alignment (undefined::a)-  peek p = peek (castPtr p) >>= \a -> return (a:.())-  peekByteOff p o = peek (p`plusPtr`o)-  peekElemOff p i = peek (p`plusPtr`(i*sizeOf(undefined::a)))-  poke p (a:._) = poke (castPtr p) a-  pokeByteOff p o x = poke (p`plusPtr`o) x-  pokeElemOff p i x = poke (p`plusPtr`(i*sizeOf(undefined::a))) x-  {-# INLINE sizeOf #-}-  {-# INLINE alignment #-}-  {-# INLINE peek #-}-  {-# INLINE peekByteOff #-}-  {-# INLINE peekElemOff #-}-  {-# INLINE poke #-}-  {-# INLINE pokeByteOff #-}-  {-# INLINE pokeElemOff #-}--instance (Vec (Succ (Succ n)) a (a:.a:.v), Storable a, Storable (a:.v)) -  => Storable (a:.a:.v) -  where-  sizeOf _ = sizeOf (undefined::a) + sizeOf (undefined::(a:.v))-  alignment _ = alignment (undefined::a)-  peek p = -    peek (castPtr p) >>= \a -> -    peek (castPtr (p`plusPtr`sizeOf(undefined::a))) >>= \v -> -    return (a:.v)-  peekByteOff p o = peek (p`plusPtr`o)-  peekElemOff p i = peek (p`plusPtr`(i*sizeOf(undefined::(a:.a:.v))))-  poke p (a:.v) = -    poke (castPtr p) a >> -    poke (castPtr (p`plusPtr`sizeOf(undefined::a))) v-  pokeByteOff p o x = poke (p`plusPtr`o) x-  pokeElemOff p i x = poke (p`plusPtr`(i*sizeOf(undefined::(a:.a:.v)))) x-  {-# INLINE sizeOf #-}-  {-# INLINE alignment #-}-  {-# INLINE peek #-}-  {-# INLINE peekByteOff #-}-  {-# INLINE peekElemOff #-}-  {-# INLINE poke #-}-  {-# INLINE pokeByteOff #-}-  {-# INLINE pokeElemOff #-}----- Num and Fractional instances : All arithmetic is done component-wise and--- literals construct uniform vectors and matrices. ------ The rule is : ---    If the method is unary, it's a map.  ---    If it's binary, it's a zipWith.--instance-    (Eq (a:.u)-    ,Show (a:.u)-    ,Num a-    ,Map a a (a:.u) (a:.u) -    ,ZipWith a a a (a:.u) (a:.u) (a:.u)-    ,Vec (Succ l) a (a:.u)-    )-    => Num (a:.u) -  where-    (+) u v = V.zipWith (+) u v -    (-) u v = V.zipWith (-) u v-    (*) u v = V.zipWith (*) u v-    abs u = V.map abs u-    signum u = V.map signum u-    fromInteger i = vec (fromInteger i)-    {-# INLINE (+) #-}-    {-# INLINE (-) #-}-    {-# INLINE (*) #-}-    {-# INLINE abs #-}-    {-# INLINE signum #-}-    {-# INLINE fromInteger #-}---instance -    (Fractional a-    ,Ord (a:.u)-    ,ZipWith a a a (a:.u) (a:.u) (a:.u)-    ,Map a a (a:.u) (a:.u)-    ,Vec (Succ l) a (a:.u)-    ,Show (a:.u)-    ) -    => Fractional (a:.u) -  where-    (/) u v = V.zipWith (/) u v-    recip u = V.map recip u-    fromRational r = vec (fromRational r)-    {-# INLINE (/) #-}-    {-# INLINE recip #-}-    {-# INLINE fromRational #-}------ Arbitrary instances--instance Arbitrary a => Arbitrary (a:.()) where-  arbitrary = arbitrary >>= return . (:.())-  coarbitrary (a:._) = variant 0 . coarbitrary a--instance (Length (a:.v) (Succ n), Arbitrary a', Arbitrary (a:.v)) => Arbitrary (a':.a:.v) where-  arbitrary = arbitrary >>= \a -> -              arbitrary >>= \v -> return (a:.v);-  coarbitrary (a:.v) = variant (V.length v) . coarbitrary a . coarbitrary v--  
Data/Vec/LinAlg.hs view
@@ -1,17 +1,15 @@ {- Copyright (c) 2008, Scott E. Dillard. All rights reserved. -} -{-# LANGUAGE BangPatterns #-} {-# LANGUAGE EmptyDataDecls #-}-{-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE NoMonomorphismRestriction #-}-{-# LANGUAGE PatternSignatures #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE OverlappingInstances #-} {-# LANGUAGE UndecidableInstances #-}  {-# OPTIONS_HADDOCK ignore-exports,prune #-}@@ -58,7 +56,9 @@ import Control.Monad import Data.Maybe +import Unsafe.Coerce + -- | dot / inner / scalar product dot ::  (Num a, Num v, Fold a v) => v -> v -> a dot u v = sum (u*v)@@ -351,11 +351,11 @@   alternating :: n -> a -> v  instance Alternating N1 a (a:.()) where-  alternating _ !a = a:.()+  alternating _ a = a:.()   {-# INLINE alternating #-}  instance (Num a, Alternating n a (a:.v)) => Alternating (Succ n) a (a:.a:.v) where-  alternating _ !a = a:.(alternating (undefined::n) (negate $! a))+  alternating _ a = a:.(alternating (undefined::n) (negate a))   {-# INLINE alternating #-}  @@ -367,9 +367,36 @@   det' ( (a:.b:.()) :. (c:.d:.()) :. () ) = a*d-b*c   {-# INLINE det' #-} ---this instance is particularly ugly in order to avoid overlapping with the one above++--This is the only overlapping instance in the whole library (goddamnit) instance     (Num a+    ,Fold a v+    ,Num v+    ,Head m v+    ,Vec n a v+    ,Map m__ a vm v+    ,Transpose vmt vm+    ,DropConsec v vv+    ,Map v vv m_ vmt+    ,Tail m m_+    ,Alternating n a v+    ,Det' a m__+    )+    => Det' a m+  where+    det' m =+      sum ((alternating undefined 1) * (head m) *+           (map det' (transpose(map(dropConsec)(tail m)))))+    {-# INLINE det' #-}++--For reference, here is the non-overlapping instance that worked in 6.8. When+--I figure out what happened between 6.8 and 6.10, hopefully we can go back to+--a non-overlapping instance.++{-+instance+    (Num a     ,Num (a:.a:.a:.v)     ,Fold a (a:.a:.a:.v)     ,Alternating (Succ (Succ (Succ n))) a (a:.a:.a:.v)@@ -388,6 +415,8 @@       sum ((alternating undefined 1) * mh *           (map det' (transpose (map dropConsec mt :: vmt))))     {-# INLINE det' #-}+-}+   -- For now, use wrapper class to allow type inference. I think maybe the
Data/Vec/Packed.hs view
@@ -39,8 +39,8 @@ -- arguments to be unpacked, but the result is a polymorphic vector @(:.)@, so -- you will need to pack it again. I admit that this is awkward.  ----- There are also instances for 'Take', 'Drop', 'Last', 'Head', 'Tail' and--- 'Snoc'. These come in handy for thinks like quaternions and homogenous+-- There are also instances for 'Access', 'Take', 'Drop', 'Last', 'Head', 'Tail' and+-- 'Snoc'. These come in handy for things like quaternions and homogenous -- coordinates.  module Data.Vec.Packed where@@ -301,3 +301,19 @@   where   drop n v = pack (drop n (unpack v))   {-# INLINE drop #-}++instance (Access n a v, PackedVec v) => Access n a (Packed v)+  where+  get n v = get n (unpack v)+  set n a v = pack (set n a (unpack v))+  {-# INLINE get #-}+  {-# INLINE set #-}++instance (VecList a v, PackedVec v) => VecList a (Packed v)+  where+  fromList    = pack . fromList+  getElem i   = getElem i . unpack+  setElem i a = pack . setElem i a . unpack+  {-# INLINE setElem #-}+  {-# INLINE getElem #-}+  {-# INLINE fromList #-}
Vec.cabal view
@@ -1,5 +1,5 @@ Name:                Vec-Version:             0.9.2+Version:             0.9.3 License:             BSD3 License-file:        LICENSE Author:              Scott E. Dillard@@ -19,25 +19,23 @@ Category:            Data,Math  library-    Build-Depends:      base,QuickCheck+    Build-Depends:      base,QuickCheck<2      Exposed-modules:    Data.Vec                          Data.Vec.Base,                         Data.Vec.LinAlg,                         Data.Vec.Nat,-                        Data.Vec.Instances                         Data.Vec.Packed     Extensions: -                        BangPatterns,                         EmptyDataDecls,-                        ExistentialQuantification,-                        FlexibleInstances,                          FlexibleContexts,+                        FlexibleInstances,                          FunctionalDependencies,                         MultiParamTypeClasses,                          NoMonomorphismRestriction,+                        OverlappingInstances,                         ScopedTypeVariables,+                        TypeFamilies,                         TypeOperators,                          TypeSynonymInstances,-                        TypeFamilies,                         UndecidableInstances