comfort-array 0.3 → 0.3.1
raw patch · 8 files changed
+144/−14 lines, 8 filesdep +containersdep ~primitivePVP ok
version bump matches the API change (PVP)
Dependencies added: containers
Dependency ranges changed: primitive
API changes (from Hackage documentation)
+ Data.Array.Comfort.Boxed: fromMap :: Ord k => Map k a -> Array (Set k) a
+ Data.Array.Comfort.Boxed: indices :: Indexed sh => sh -> Array sh (Index sh)
+ Data.Array.Comfort.Shape: instance GHC.Classes.Ord n => Data.Array.Comfort.Shape.C (Data.Set.Internal.Set n)
+ Data.Array.Comfort.Shape: instance GHC.Classes.Ord n => Data.Array.Comfort.Shape.Indexed (Data.Set.Internal.Set n)
+ Data.Array.Comfort.Shape: instance GHC.Classes.Ord n => Data.Array.Comfort.Shape.InvIndexed (Data.Set.Internal.Set n)
+ Data.Array.Comfort.Storable: fromBoxed :: (C sh, Storable a) => Array sh a -> Array sh a
+ Data.Array.Comfort.Storable: fromMap :: (Ord k, Storable a) => Map k a -> Array (Set k) a
+ Data.Array.Comfort.Storable: sample :: (Indexed sh, Storable a) => sh -> (Index sh -> a) -> Array sh a
+ Data.Array.Comfort.Storable: toBoxed :: (C sh, Storable a) => Array sh a -> Array sh a
Files
- comfort-array.cabal +21/−6
- set/0.4.0/Data/Array/Comfort/Shape/Set.hs +31/−0
- set/0.5.4/Data/Array/Comfort/Shape/Set.hs +13/−0
- src/Data/Array/Comfort/Boxed.hs +12/−0
- src/Data/Array/Comfort/Shape.hs +26/−7
- src/Data/Array/Comfort/Shape/Utility.hs +8/−0
- src/Data/Array/Comfort/Storable.hs +28/−1
- test/Test/Shape.hs +5/−0
comfort-array.cabal view
@@ -1,5 +1,5 @@ Name: comfort-array-Version: 0.3+Version: 0.3.1 License: BSD3 License-File: LICENSE Author: Henning Thielemann <haskell@henning-thielemann.de>@@ -33,9 +33,6 @@ E.g. a non-negative index type like 'Word' cannot represent @-1@ and thus cannot encode an empty range starting with index @0@. .- * @Square@:- An 2D array where both dimensions always have equal size.- . * @ZeroBased, OneBased@: Arrays with fixed lower bound, either 0 or 1, respectively. .@@ -43,8 +40,12 @@ The Append type constructor allows to respresent block arrays, e.g. block matrices. .- * Arrays with indices like 'LT', 'EQ', 'GT' and dummy shape.+ * @Enumeration@: Arrays with indices like 'LT', 'EQ', 'GT' and dummy shape. .+ * @Set@: Use an arbitrary ordered set as index set.+ .+ * @Triangular@: A 2D array with the shape of lower or upper triangular matrix.+ . The @lapack@ package defines even more fancy shapes like tall rectangular matrices, triangular matrices and banded matrices. @@ -55,7 +56,7 @@ Changes.md Source-Repository this- Tag: 0.3+ Tag: 0.3.1 Type: darcs Location: http://hub.darcs.net/thielema/comfort-array/ @@ -63,6 +64,10 @@ Type: darcs Location: http://hub.darcs.net/thielema/comfort-array/ +Flag setIndex+ Description: Use efficient Set indexing from containers>=0.5.4+ Default: True+ Library Build-Depends: primitive >=0.6.4 && <0.7,@@ -70,11 +75,18 @@ storable-record >=0.0.1 && <0.1, deepseq >=1.3 && <1.5, QuickCheck >=2 && <3,+ containers >=0.4 && <0.7, transformers >=0.3 && <0.6, non-empty >=0.3 && <0.4, utility-ht >=0.0.10 && <0.1, base >=4.5 && <5 + If flag(setIndex)+ Build-Depends: containers >=0.5.4+ Hs-Source-Dirs: set/0.5.4+ Else+ Hs-Source-Dirs: set/0.4.0+ GHC-Options: -Wall Default-Language: Haskell98 Hs-Source-Dirs: src@@ -90,12 +102,15 @@ Data.Array.Comfort.Storable.Mutable.Private Data.Array.Comfort.Boxed Other-Modules:+ Data.Array.Comfort.Shape.Set+ Data.Array.Comfort.Shape.Utility Data.Array.Comfort.Boxed.Unchecked Test-Suite comfort-array-test Type: exitcode-stdio-1.0 Build-Depends: comfort-array,+ containers, QuickCheck, base
+ set/0.4.0/Data/Array/Comfort/Shape/Set.hs view
@@ -0,0 +1,31 @@+module Data.Array.Comfort.Shape.Set where++import Data.Array.Comfort.Shape.Utility (errorIndexFromOffset)++import qualified Data.Set as Set+import Data.Set (Set)+import Data.Tuple.HT (fst3)+++offset :: Ord a => Set a -> a -> Int+offset set ix =+ case Set.splitMember ix set of+ (less, hit, _) ->+ if hit+ then Set.size less+ else error "Shape.Set: array index not member of the index set"++uncheckedOffset :: Ord a => Set a -> a -> Int+uncheckedOffset set = Set.size . fst3 . flip Set.splitMember set++indexFromOffset :: Set a -> Int -> a+indexFromOffset set k =+ if 0<=k+ then uncheckedIndexFromOffset set k+ else errorIndexFromOffset "Set" k++uncheckedIndexFromOffset :: Set a -> Int -> a+uncheckedIndexFromOffset set k =+ case drop k $ Set.toAscList set of+ [] -> errorIndexFromOffset "Set" k+ ix:_ -> ix
+ set/0.5.4/Data/Array/Comfort/Shape/Set.hs view
@@ -0,0 +1,13 @@+module Data.Array.Comfort.Shape.Set where++import qualified Data.Set as Set+import Data.Set (Set)+++offset, uncheckedOffset :: Ord a => Set a -> a -> Int+offset = flip Set.findIndex+uncheckedOffset = offset++indexFromOffset, uncheckedIndexFromOffset :: Set a -> Int -> a+indexFromOffset = flip Set.elemAt+uncheckedIndexFromOffset = indexFromOffset
src/Data/Array/Comfort/Boxed.hs view
@@ -5,7 +5,9 @@ Array.toList, toAssociations, Array.fromList,+ fromMap, Array.vectorFromList,+ indices, Array.map, zipWith,@@ -24,6 +26,9 @@ import Control.Monad.ST (runST) import Control.Applicative ((<$>)) +import qualified Data.Map as Map+import Data.Map (Map)+import Data.Set (Set) import Data.Foldable (forM_) import Prelude hiding (zipWith)@@ -31,6 +36,13 @@ shape :: Array.Array sh a -> sh shape = Array.shape+++indices :: (Shape.Indexed sh) => sh -> Array.Array sh (Shape.Index sh)+indices sh = Array.fromList sh $ Shape.indices sh++fromMap :: (Ord k) => Map k a -> Array (Set k) a+fromMap m = Array.fromList (Map.keysSet m) (Map.elems m) infixl 9 !
src/Data/Array/Comfort/Shape.hs view
@@ -21,6 +21,9 @@ triangleSize, triangleRoot, ) where +import qualified Data.Array.Comfort.Shape.Set as ShapeSet+import Data.Array.Comfort.Shape.Utility (errorIndexFromOffset)+ import qualified Foreign.Storable.Newtype as Store import Foreign.Storable (Storable, sizeOf, alignment, poke, peek, pokeElemOff, peekElemOff)@@ -35,9 +38,9 @@ import Control.Applicative (Applicative, pure, liftA2, liftA3, (<*>)) import Control.Applicative (Const(Const, getConst)) -import Text.Printf (printf)-+import qualified Data.Set as Set import qualified Data.NonEmpty as NonEmpty+import Data.Set (Set) import Data.List.HT (tails) import Data.Tuple.HT (mapSnd, mapPair, swap, fst3, snd3, thd3) @@ -77,11 +80,7 @@ uncheckedIndexFromOffset :: sh -> Int -> Index sh uncheckedIndexFromOffset = indexFromOffset -errorIndexFromOffset :: String -> Int -> a-errorIndexFromOffset name k =- error $ printf "indexFromOffset (%s): index %d out of range" name k - instance C () where size () = 1 uncheckedSize () = 1@@ -301,7 +300,7 @@ {- | 'Enumeration' denotes a shape of fixed size that is defined by 'Enum' and 'Bounded' methods.-For correctness it is necessary that the 'Enum' and 'Bounded'+For correctness it is necessary that the 'Enum' and 'Bounded' instances are properly implemented. Automatically derived instances are fine. -}@@ -344,6 +343,26 @@ alignment ~Enumeration = 1 poke _p Enumeration = return () peek _p = return Enumeration+++{- |+You can use an arbitrary 'Set' of indices as shape.+The array elements are ordered according to the index order in the 'Set'.+-}+instance (Ord n) => C (Set n) where+ size = uncheckedSize+ uncheckedSize = Set.size++instance (Ord n) => Indexed (Set n) where+ type Index (Set n) = n+ indices = Set.toAscList+ offset = ShapeSet.offset+ uncheckedOffset = ShapeSet.uncheckedOffset+ inBounds = flip Set.member++instance (Ord n) => InvIndexed (Set n) where+ indexFromOffset = ShapeSet.indexFromOffset+ uncheckedIndexFromOffset = ShapeSet.uncheckedIndexFromOffset {- |
+ src/Data/Array/Comfort/Shape/Utility.hs view
@@ -0,0 +1,8 @@+module Data.Array.Comfort.Shape.Utility where++import Text.Printf (printf)+++errorIndexFromOffset :: String -> Int -> a+errorIndexFromOffset name k =+ error $ printf "indexFromOffset (%s): index %d out of range" name k
src/Data/Array/Comfort/Storable.hs view
@@ -6,8 +6,12 @@ (!), Array.toList,- Array.fromList,+ fromList,+ fromMap, Array.vectorFromList,+ sample,+ fromBoxed,+ toBoxed, Array.map, Array.mapWithIndex,@@ -19,6 +23,7 @@ import qualified Data.Array.Comfort.Storable.Mutable.Unchecked as MutArrayNC import qualified Data.Array.Comfort.Storable.Mutable as MutArray import qualified Data.Array.Comfort.Storable.Unchecked as Array+import qualified Data.Array.Comfort.Boxed as BoxedArray import qualified Data.Array.Comfort.Shape as Shape import Data.Array.Comfort.Storable.Unchecked (Array) @@ -26,6 +31,10 @@ import Control.Monad.ST (runST) +import qualified Data.Map as Map+import qualified Data.List as List+import Data.Map (Map)+import Data.Set (Set) import Data.Foldable (forM_) import Text.Printf (printf)@@ -51,6 +60,24 @@ mapShape :: (Shape.C sh0, Shape.C sh1) => (sh0 -> sh1) -> Array sh0 a -> Array sh1 a mapShape f arr = reshape (f $ shape arr) arr+++fromList :: (Shape.C sh, Storable a) => sh -> [a] -> Array sh a+fromList sh arr = runST (MutArrayNC.unsafeFreeze =<< MutArray.fromList sh arr)++fromMap :: (Ord k, Storable a) => Map k a -> Array (Set k) a+fromMap m = fromList (Map.keysSet m) (Map.elems m)++sample ::+ (Shape.Indexed sh, Storable a) => sh -> (Shape.Index sh -> a) -> Array sh a+sample sh f = Array.fromList sh $ List.map f $ Shape.indices sh+++fromBoxed :: (Shape.C sh, Storable a) => BoxedArray.Array sh a -> Array sh a+fromBoxed arr = Array.fromList (BoxedArray.shape arr) $ BoxedArray.toList arr++toBoxed :: (Shape.C sh, Storable a) => Array sh a -> BoxedArray.Array sh a+toBoxed arr = BoxedArray.fromList (Array.shape arr) $ Array.toList arr infixl 9 !
test/Test/Shape.hs view
@@ -9,7 +9,9 @@ import Control.Applicative (liftA2, liftA3) +import qualified Data.Set as Set + genZeroBased :: Int -> QC.Gen (Shape.ZeroBased Int) genZeroBased n = fmap Shape.ZeroBased $ QC.choose (0,n) @@ -34,6 +36,9 @@ prefix "Enumeration Ordering" (ShapeTest.tests $ return (Shape.Enumeration :: Shape.Enumeration Ordering)) +++ prefix "Set"+ (ShapeTest.tests $+ fmap Set.fromList (QC.listOf (QC.choose ('a','z')))) ++ prefix "Deferred Shifted" (ShapeTest.tests $ fmap Shape.Deferred $ liftA2 Shape.Shifted