packages feed

mnist-idx 0.1.2.4 → 0.1.2.5

raw patch · 3 files changed

+136/−136 lines, 3 filesdep ~basePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: base

API changes (from Hackage documentation)

- Data.IDX: instance Data.Binary.Class.Binary Data.IDX.Internal.IDXContentType
- Data.IDX: instance Data.Binary.Class.Binary Data.IDX.Internal.IDXData
- Data.IDX: instance Data.Binary.Class.Binary Data.IDX.Internal.IDXLabels
+ Data.IDX.Internal: buildDoubleResult :: Real a => Int -> IDXContentType -> Vector Int -> Get a -> Get IDXData
+ Data.IDX.Internal: buildIntResult :: Integral a => Int -> IDXContentType -> Vector Int -> Get a -> Get IDXData
+ Data.IDX.Internal: getDouble :: Get Double
+ Data.IDX.Internal: getFloat :: Get Float
+ Data.IDX.Internal: getInt16 :: Get Int16
+ Data.IDX.Internal: getInt32 :: Get Int32
+ Data.IDX.Internal: getInt8 :: Get Int8
+ Data.IDX.Internal: instance Data.Binary.Class.Binary Data.IDX.Internal.IDXContentType
+ Data.IDX.Internal: instance Data.Binary.Class.Binary Data.IDX.Internal.IDXData
+ Data.IDX.Internal: instance Data.Binary.Class.Binary Data.IDX.Internal.IDXLabels
+ Data.IDX.Internal: putIntegral :: IDXContentType -> Int -> Put
+ Data.IDX.Internal: putReal :: IDXContentType -> Double -> Put

Files

mnist-idx.cabal view
@@ -1,6 +1,6 @@ name:                mnist-idx -version:             0.1.2.4+version:             0.1.2.5  -- A short (one-line) description of the package. synopsis:            Read and write IDX data that is used in e.g. the MNIST database.
src/Data/IDX.hs view
@@ -10,7 +10,7 @@ -- -- A package for reading and writing data in the IDX format. -- This data format is used for machine-learning data sets like the--- MINST database of handwritten digits (<http://yann.lecun.com/exdb/mnist/>)+-- MNIST database of handwritten digits (<http://yann.lecun.com/exdb/mnist/>) -------------------------------------------------------------------------------- module Data.IDX (                 -- * Data types@@ -70,41 +70,6 @@ import           Data.Vector.Unboxed ((!)) import           Data.Word -import Debug.Trace--instance Binary IDXContentType where-    get = do-      w <- getWord8-      case w of-        0x08 -> return IDXUnsignedByte-        0x09 -> return IDXSignedByte-        0x0B -> return IDXShort-        0x0C -> return IDXInt-        0x0D -> return IDXFloat-        0x0E -> return IDXDouble-        _ -> fail $ "Unrecognized IDX content type: " ++ (show w)-        -    put IDXUnsignedByte = putWord8 0x08-    put IDXSignedByte   = putWord8 0x09-    put IDXShort        = putWord8 0x0B-    put IDXInt          = putWord8 0x0C-    put IDXFloat        = putWord8 0x0D-    put IDXDouble       = putWord8 0x0E--instance Binary IDXLabels where-  get = do-    getInt32-    nItems <- fromIntegral <$> getInt32-    let readEntries n = V.replicateM n $ fromIntegral <$> getWord8 >>= (return $!)-    v <- readContent readEntries 500 nItems-    return $ IDXLabels v--  put (IDXLabels v) = do-    put (0 :: Int32)-    let len = V.length v-    put (fromIntegral len :: Int32)-    V.forM_ v (\x -> put $! (fromIntegral x :: Word8))- -- | Partition a dataset and label each subpartition, return int values labeledIntData:: IDXLabels -> IDXData -> Maybe [(Int, V.Vector Int)] labeledIntData (IDXLabels v) dat =@@ -133,105 +98,6 @@     content = idxDoubleContent dat     entrySize = (V.product $ idxDimensions dat) `div` dim0 -instance Binary IDXData where-    get = do-      -- Get header information (4 bytes total)-      getWord8-      getWord8 -      idxType <- get :: Get IDXContentType-      nDimensions <- fromIntegral <$> getWord8--      -- Each dimension size is encoded as a 32 bit integer-      dimensionSizes <- replicateM nDimensions (fromIntegral <$> getInt32)      -      let nEntries = fromIntegral $ product dimensionSizes-          dimV = V.fromList dimensionSizes--      -- Retrieve the data, depending on the type specified in the file-      -- Cast all integral types to Int and all decimal numbers tod double-      case idxType of-        t@IDXUnsignedByte -> buildIntResult nEntries t dimV getWord8-        t@IDXSignedByte   -> buildIntResult nEntries t dimV getInt8-        t@IDXShort        -> buildIntResult nEntries t dimV getInt16-        t@IDXInt          -> buildIntResult nEntries t dimV getInt32--        t@IDXFloat        -> buildDoubleResult nEntries t dimV getFloat-        t@IDXDouble       -> buildDoubleResult nEntries t dimV getDouble-        -    put d = do-      -- First four bytes are meta information-      putWord8 0-      putWord8 0-      -- Third byte is content type-      put $ idxType d-      -      -- Fourth byte is number of dimensions-      let dimensions = idxDimensions d-      put $ (fromIntegral $ V.length dimensions :: Word8)--      -- Put size of each dimension as an Int32-      V.forM_ dimensions $ (\x -> put $! (fromIntegral x :: Int32))--      -- Put the individual values-      case d of-        IDXDoubles t _ content -> V.forM_ content $ putReal     t-        IDXInts    t _ content -> V.forM_ content $ putIntegral t---- | Helper function for parsing integer data from the--- IDX content. Returns a full IDX result.-buildIntResult :: Integral a-                  => Int                -- ^ Expected number of entries-                      -> IDXContentType -- ^ Description of content-                      -> V.Vector Int   -- ^ Dimension sizes-                      -> Get a          -- ^ Monadic action to get content element-                      -> Get IDXData-buildIntResult nEntries typ dimV getContent = do-  content <- readContent readEntries 500 nEntries-  return $ IDXInts typ dimV content-  where-    readEntries n = V.replicateM n $ fromIntegral <$> getContent >>= (return $!)---- | Helper function for parsing real number data from--- the IDX content.-buildDoubleResult :: Real a-                  => Int                -- ^ Expected number of entries-                      -> IDXContentType -- ^ Description of content-                      -> V.Vector Int   -- ^ Dimension sizes-                      -> Get a          -- ^ Monadic action to get content element-                      -> Get IDXData-buildDoubleResult nEntries typ dimV getContent = do-  content <- readContent readEntries 500 nEntries-  return $ IDXDoubles typ dimV content-  where-    readEntries n = V.replicateM n $ realToFrac <$> getContent >>= (return $!)---- | Put values that are saved as Int-putIntegral :: IDXContentType -> Int -> Put-putIntegral IDXUnsignedByte n = put $! (fromIntegral n :: Word8)-putIntegral IDXSignedByte   n = put $! (fromIntegral n :: Int8 )-putIntegral IDXShort        n = put $! (fromIntegral n :: Int16)-putIntegral IDXInt          n = put $! (fromIntegral n :: Int32)-putIntegral t               _ = error $ "IDX.putIntegral " ++ show t ---- | Put real values that are saved as Double-putReal :: IDXContentType -> Double -> Put-putReal IDXDouble n = put n-putReal IDXFloat  n = put $! (realToFrac n :: Float )---- Haskell's Data.Binary uses big-endian format-getInt8 :: Get Int8-getInt8 = get--getInt16 :: Get Int16-getInt16 = get--getInt32 :: Get Int32-getInt32 = get--getFloat :: Get Float-getFloat = get--getDouble :: Get Double-getDouble = get  -- | Read labels from a file, return 'Nothing' if something doesn't work decodeIDXLabelsFile :: FilePath -> IO (Maybe IDXLabels)
src/Data/IDX/Internal.hs view
@@ -19,6 +19,7 @@  import           Control.Monad (replicateM) import           Data.Binary+import           Data.Int  import qualified Data.Vector.Unboxed as V import           Data.Vector.Unboxed ((!))@@ -33,7 +34,25 @@    IDXDouble       :: IDXContentType    deriving Show +instance Binary IDXContentType where+    get = do+      w <- getWord8+      case w of+        0x08 -> return IDXUnsignedByte+        0x09 -> return IDXSignedByte+        0x0B -> return IDXShort+        0x0C -> return IDXInt+        0x0D -> return IDXFloat+        0x0E -> return IDXDouble+        _ -> fail $ "Unrecognized IDX content type: " ++ (show w) +    put IDXUnsignedByte = putWord8 0x08+    put IDXSignedByte   = putWord8 0x09+    put IDXShort        = putWord8 0x0B+    put IDXInt          = putWord8 0x0C+    put IDXFloat        = putWord8 0x0D+    put IDXDouble       = putWord8 0x0E+ -- | Datatype for storing IDXData. Internally data is always stored either -- as 'Int' or 'Double' unboxed vectors. However when binary serialization -- is used, the data is serialized according to the 'IDXContentType'.@@ -41,9 +60,68 @@              | IDXDoubles IDXContentType (V.Vector Int) (V.Vector Double)              deriving Show ++instance Binary IDXData where+    get = do+      -- Get header information (4 bytes total)+      getWord8+      getWord8 +      idxType <- get :: Get IDXContentType+      nDimensions <- fromIntegral <$> getWord8++      -- Each dimension size is encoded as a 32 bit integer+      dimensionSizes <- replicateM nDimensions (fromIntegral <$> getInt32)      +      let nEntries = fromIntegral $ product dimensionSizes+          dimV = V.fromList dimensionSizes++      -- Retrieve the data, depending on the type specified in the file+      -- Cast all integral types to Int and all decimal numbers tod double+      case idxType of+        t@IDXUnsignedByte -> buildIntResult nEntries t dimV getWord8+        t@IDXSignedByte   -> buildIntResult nEntries t dimV getInt8+        t@IDXShort        -> buildIntResult nEntries t dimV getInt16+        t@IDXInt          -> buildIntResult nEntries t dimV getInt32++        t@IDXFloat        -> buildDoubleResult nEntries t dimV getFloat+        t@IDXDouble       -> buildDoubleResult nEntries t dimV getDouble+        +    put d = do+      -- First four bytes are meta information+      putWord8 0+      putWord8 0+      -- Third byte is content type+      put $ idxType d+      +      -- Fourth byte is number of dimensions+      let dimensions = idxDimensions d+      put $ (fromIntegral $ V.length dimensions :: Word8)++      -- Put size of each dimension as an Int32+      V.forM_ dimensions $ (\x -> put $! (fromIntegral x :: Int32))++      -- Put the individual values+      case d of+        IDXDoubles t _ content -> V.forM_ content $ putReal     t+        IDXInts    t _ content -> V.forM_ content $ putIntegral t++-- | A data type that holds 'Int' labels for a set of 'IDXData' newtype IDXLabels = IDXLabels (V.Vector Int) +instance Binary IDXLabels where+  get = do+    getInt32+    nItems <- fromIntegral <$> getInt32+    let readEntries n = V.replicateM n $ fromIntegral <$> getWord8 >>= (return $!)+    v <- readContent readEntries 500 nItems+    return $ IDXLabels v +  put (IDXLabels v) = do+    put (0 :: Int32)+    let len = V.length v+    put (fromIntegral len :: Int32)+    V.forM_ v (\x -> put $! (fromIntegral x :: Word8))++ -- | Return the what type the data is stored in idxType :: IDXData -> IDXContentType idxType (IDXInts    t _ _) = t@@ -101,3 +179,59 @@     rest <- readEntries n     return $! rest +-- Haskell's Data.Binary uses big-endian format+getInt8 :: Get Int8+getInt8 = get++getInt16 :: Get Int16+getInt16 = get++getInt32 :: Get Int32+getInt32 = get++getFloat :: Get Float+getFloat = get++getDouble :: Get Double+getDouble = get++-- | Helper function for parsing integer data from the+-- IDX content. Returns a full IDX result.+buildIntResult :: Integral a+                  => Int                -- ^ Expected number of entries+                      -> IDXContentType -- ^ Description of content+                      -> V.Vector Int   -- ^ Dimension sizes+                      -> Get a          -- ^ Monadic action to get content element+                      -> Get IDXData+buildIntResult nEntries typ dimV getContent = do+  content <- readContent readEntries 500 nEntries+  return $ IDXInts typ dimV content+  where+    readEntries n = V.replicateM n $ fromIntegral <$> getContent >>= (return $!)++-- | Helper function for parsing real number data from+-- the IDX content.+buildDoubleResult :: Real a+                  => Int                -- ^ Expected number of entries+                      -> IDXContentType -- ^ Description of content+                      -> V.Vector Int   -- ^ Dimension sizes+                      -> Get a          -- ^ Monadic action to get content element+                      -> Get IDXData+buildDoubleResult nEntries typ dimV getContent = do+  content <- readContent readEntries 500 nEntries+  return $ IDXDoubles typ dimV content+  where+    readEntries n = V.replicateM n $ realToFrac <$> getContent >>= (return $!)++-- | Put values that are saved as Int+putIntegral :: IDXContentType -> Int -> Put+putIntegral IDXUnsignedByte n = put $! (fromIntegral n :: Word8)+putIntegral IDXSignedByte   n = put $! (fromIntegral n :: Int8 )+putIntegral IDXShort        n = put $! (fromIntegral n :: Int16)+putIntegral IDXInt          n = put $! (fromIntegral n :: Int32)+putIntegral t               _ = error $ "IDX.putIntegral " ++ show t ++-- | Put real values that are saved as Double+putReal :: IDXContentType -> Double -> Put+putReal IDXDouble n = put n+putReal IDXFloat  n = put $! (realToFrac n :: Float )