packages feed

multilinear-io 0.2.3 → 0.3.0.0

raw patch · 8 files changed

+60/−49 lines, 8 filesdep ~multilinearsetup-changedPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: multilinear

API changes (from Hackage documentation)

- Multilinear.Generic.Serialize: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Multilinear.Generic.Tensor a)
- Multilinear.Generic.Serialize: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Multilinear.Generic.Tensor a)
- Multilinear.Generic.Serialize: instance Data.Csv.Conversion.FromField a => Data.Csv.Conversion.FromRecord (Multilinear.Generic.Tensor a)
- Multilinear.Generic.Serialize: instance Data.Csv.Conversion.ToField a => Data.Csv.Conversion.ToRecord (Multilinear.Generic.Tensor a)
- Multilinear.Generic.Serialize: instance Data.Serialize.Serialize a => Data.Serialize.Serialize (Multilinear.Generic.Tensor a)
+ Multilinear.Generic.Serialize: instance (Data.Aeson.Types.FromJSON.FromJSON a, Data.Vector.Unboxed.Base.Unbox a) => Data.Aeson.Types.FromJSON.FromJSON (Multilinear.Generic.Tensor a)
+ Multilinear.Generic.Serialize: instance (Data.Aeson.Types.ToJSON.ToJSON a, Data.Vector.Unboxed.Base.Unbox a) => Data.Aeson.Types.ToJSON.ToJSON (Multilinear.Generic.Tensor a)
+ Multilinear.Generic.Serialize: instance (Data.Csv.Conversion.FromField a, Data.Vector.Unboxed.Base.Unbox a) => Data.Csv.Conversion.FromRecord (Multilinear.Generic.Tensor a)
+ Multilinear.Generic.Serialize: instance (Data.Csv.Conversion.ToField a, Data.Vector.Unboxed.Base.Unbox a) => Data.Csv.Conversion.ToRecord (Multilinear.Generic.Tensor a)
+ Multilinear.Generic.Serialize: instance (Data.Serialize.Serialize a, Data.Vector.Unboxed.Base.Unbox a) => Data.Serialize.Serialize (Multilinear.Generic.Tensor a)
- Multilinear.Generic.Serialize: fromBinary :: Serialize a => ByteString -> Either String (Tensor a)
+ Multilinear.Generic.Serialize: fromBinary :: (Serialize a, Unbox a) => ByteString -> Either String (Tensor a)
- Multilinear.Generic.Serialize: fromBinaryFile :: Serialize a => String -> ExceptT String IO (Tensor a)
+ Multilinear.Generic.Serialize: fromBinaryFile :: (Serialize a, Unbox a) => String -> ExceptT String IO (Tensor a)
- Multilinear.Generic.Serialize: fromCSVFile :: FromField a => String -> Char -> String -> ExceptT String IO (Tensor a)
+ Multilinear.Generic.Serialize: fromCSVFile :: (FromField a, Unbox a) => String -> Char -> String -> ExceptT String IO (Tensor a)
- Multilinear.Generic.Serialize: fromJSON :: FromJSON a => ByteString -> Maybe (Tensor a)
+ Multilinear.Generic.Serialize: fromJSON :: (FromJSON a, Unbox a) => ByteString -> Maybe (Tensor a)
- Multilinear.Generic.Serialize: fromJSONFile :: FromJSON a => String -> MaybeT IO (Tensor a)
+ Multilinear.Generic.Serialize: fromJSONFile :: (FromJSON a, Unbox a) => String -> MaybeT IO (Tensor a)
- Multilinear.Generic.Serialize: toBinary :: Serialize a => Tensor a -> ByteString
+ Multilinear.Generic.Serialize: toBinary :: (Serialize a, Unbox a) => Tensor a -> ByteString
- Multilinear.Generic.Serialize: toBinaryFile :: Serialize a => Tensor a -> String -> IO ()
+ Multilinear.Generic.Serialize: toBinaryFile :: (Serialize a, Unbox a) => Tensor a -> String -> IO ()
- Multilinear.Generic.Serialize: toCSVFile :: ToField a => Tensor a -> String -> IO ()
+ Multilinear.Generic.Serialize: toCSVFile :: (ToField a, Unbox a) => Tensor a -> String -> IO ()
- Multilinear.Generic.Serialize: toJSON :: ToJSON a => Tensor a -> ByteString
+ Multilinear.Generic.Serialize: toJSON :: (ToJSON a, Unbox a) => Tensor a -> ByteString
- Multilinear.Generic.Serialize: toJSONFile :: ToJSON a => Tensor a -> String -> IO ()
+ Multilinear.Generic.Serialize: toJSONFile :: (ToJSON a, Unbox a) => Tensor a -> String -> IO ()

Files

ChangeLog.md view
@@ -1,3 +1,6 @@+# 0.3.0.0, 2018-11-14
+- ported to multilinear-0.3.0.0
+
 # 0.2.3, 2018-11-02
 - IO ported to Conduit based
 - support for CSV with cassava
README.md view
@@ -1,9 +1,9 @@ # README
 
 ## Build status
-- Travis (Linux, macOS): [![Build Status](https://travis-ci.org/ArturB/multilinear.svg?branch=master)](https://travis-ci.org/ArturB/multilinear)
-- AppVeyor (Windows): [![Tests status](https://ci.appveyor.com/api/projects/status/github/ArturB/multilinear
-)](https://ci.appveyor.com/api/projects/status/github/ArturB/multilinear)
+- Travis (Linux, macOS): [![Build Status](https://travis-ci.org/ArturB/multilinear-io.svg?branch=master)](https://travis-ci.org/ArturB/multilinear-io)
+- AppVeyor (Windows): [![Tests status](https://ci.appveyor.com/api/projects/status/github/ArturB/multilinear-io
+)](https://ci.appveyor.com/api/projects/status/github/ArturB/multilinear-io)
 
 ## Summary
 This package provides conduit-based input/output capability for [Multilinear](https://github.com/ArturB/multilinear) package, in various formats:
Setup.hs view
@@ -1,2 +1,2 @@-import Distribution.Simple
-main = defaultMain
+import Distribution.Simple+main = defaultMain
multilinear-io.cabal view
@@ -1,13 +1,11 @@-cabal-version: 1.12
---- This file has been generated from package.yaml by hpack version 0.31.0.+-- This file has been generated from package.yaml by hpack version 0.28.2.
 -- -- see: https://github.com/sol/hpack ----- hash: f722f54ad6081f3a4e98e1615679d778fd0ba99c89c3d5db3165762ff54a5bd3+-- hash: 86b14a55f0044713d22b5d0d065b6241e7d37686463ad116dde83c012791e38b  name:           multilinear-io-version:        0.2.3+version:        0.3.0.0 synopsis:       Input/output capability for multilinear package. description:    Input & output capability for multilinear package <https://hackage.haskell.org/package/multilinear>. Supports various file formats: binary, CSV, JSON. More information available on GitHub: <https://github.com/ArturB/multilinear-io#readme> category:       Machine learning@@ -19,9 +17,10 @@ license:        BSD3 license-file:   LICENSE build-type:     Simple+cabal-version:  >= 1.10 extra-source-files:-    README.md     ChangeLog.md+    README.md  source-repository head   type: git@@ -37,7 +36,7 @@   hs-source-dirs:       src   default-extensions: DeriveGeneric FlexibleContexts FlexibleInstances MultiParamTypeClasses ScopedTypeVariables-  ghc-options: -O2 -Wall+  ghc-options: -O2 -W   build-depends:       aeson     , base >=4.7 && <5@@ -47,7 +46,7 @@     , cereal-vector     , conduit     , either-    , multilinear >=0.2.0 && <0.3+    , multilinear     , transformers     , vector     , zlib@@ -61,12 +60,12 @@   hs-source-dirs:       test/binary   default-extensions: DeriveGeneric FlexibleContexts FlexibleInstances MultiParamTypeClasses ScopedTypeVariables-  ghc-options: -O2 -Wall -threaded -rtsopts -with-rtsopts=-N+  ghc-options: -O2 -W -threaded -rtsopts -with-rtsopts=-N   build-depends:       base >=4.7 && <5     , directory     , either-    , multilinear >=0.2.0 && <0.3+    , multilinear     , multilinear-io     , transformers   default-language: Haskell2010@@ -79,12 +78,12 @@   hs-source-dirs:       test/csv   default-extensions: DeriveGeneric FlexibleContexts FlexibleInstances MultiParamTypeClasses ScopedTypeVariables-  ghc-options: -O2 -Wall -threaded -rtsopts -with-rtsopts=-N+  ghc-options: -O2 -W -threaded -rtsopts -with-rtsopts=-N   build-depends:       base >=4.7 && <5     , directory     , either-    , multilinear >=0.2.0 && <0.3+    , multilinear     , multilinear-io     , transformers   default-language: Haskell2010@@ -97,12 +96,12 @@   hs-source-dirs:       test/json   default-extensions: DeriveGeneric FlexibleContexts FlexibleInstances MultiParamTypeClasses ScopedTypeVariables-  ghc-options: -O2 -Wall -threaded -rtsopts -with-rtsopts=-N+  ghc-options: -O2 -W -threaded -rtsopts -with-rtsopts=-N   build-depends:       base >=4.7 && <5     , directory     , either-    , multilinear >=0.2.0 && <0.3+    , multilinear     , multilinear-io     , transformers   default-language: Haskell2010@@ -115,14 +114,14 @@   hs-source-dirs:       benchmark   default-extensions: DeriveGeneric FlexibleContexts FlexibleInstances MultiParamTypeClasses ScopedTypeVariables-  ghc-options: -O2 -Wall -threaded -rtsopts -with-rtsopts=-N+  ghc-options: -O2 -W -threaded -rtsopts -with-rtsopts=-N   build-depends:       base >=4.7 && <5     , criterion     , deepseq     , directory     , either-    , multilinear >=0.2.0 && <0.3+    , multilinear     , multilinear-io     , transformers   default-language: Haskell2010
src/Multilinear/Generic/Serialize.hs view
@@ -20,55 +20,54 @@ ) where
 
 import           Codec.Compression.GZip
-import           Data.Conduit
-import           Data.Conduit.Combinators
 import           Control.Monad.Trans.Class
 import           Control.Monad.Trans.Except
 import           Control.Monad.Trans.Maybe
 import           Data.Aeson
 import qualified Data.ByteString.Internal   as BS
 import qualified Data.ByteString.Lazy       as ByteString
+import           Data.Conduit
+import           Data.Conduit.Combinators
 import           Data.Csv
 import           Data.Either
 import           Data.Serialize
 import qualified Data.Vector                as Boxed
 import           Data.Vector.Serialize      ()
+import qualified Data.Vector.Unboxed        as Unboxed
 import           Multilinear.Generic
 import qualified Multilinear.Index.Finite   as Finite
 import           Multilinear.Index.Finite.Serialize ()
 import           Multilinear.Index.Infinite.Serialize ()
 
 -- Binary serialization instance
-instance Serialize a => Serialize (Tensor a)
+instance (Serialize a, Unboxed.Unbox a) => Serialize (Tensor a)
 -- JSON serialization instance
-instance ToJSON a => ToJSON (Tensor a)
+instance (ToJSON a, Unboxed.Unbox a) => ToJSON (Tensor a)
 -- JSON deserialization instance
-instance FromJSON a => FromJSON (Tensor a)
+instance (FromJSON a, Unboxed.Unbox a) => FromJSON (Tensor a)
 -- CSV serialization instance
-instance ToField a => ToRecord (Tensor a) where
+instance (ToField a, Unboxed.Unbox a) => ToRecord (Tensor a) where
   toRecord (Scalar x) = record [toField x]
   toRecord (SimpleFinite _ scalars) = toRecord scalars
   toRecord _ = error "Only 1-order tensor may be converted to record!"
-instance FromField a => FromRecord (Tensor a) where
+instance (FromField a, Unboxed.Unbox a) => FromRecord (Tensor a) where
   parseRecord v = 
     if Boxed.length v == 1 then
       Scalar <$> v .! 0
     else
-      --FiniteTensor (Finite.Covariant (Boxed.length v) "i") <$> v
       error "non-scalar"
 
 
-
 {-| Serialize tensor to zlib compressed binary string -}
 toBinary :: (
-    Serialize a 
+    Serialize a, Unboxed.Unbox a
   ) => Tensor a              -- ^ Tensor to serialize
     -> ByteString.ByteString -- ^ Tensor serialized to lazy ByteString
 toBinary = compress . Data.Serialize.encodeLazy
 
 {-| Write tensor to binary file. Uses compression with gzip -}
 toBinaryFile :: (
-    Serialize a 
+    Serialize a, Unboxed.Unbox a
   ) => Tensor a  -- ^ Tensor to serialize
     -> String    -- ^ File name
     -> IO ()
@@ -79,14 +78,14 @@ 
 {-| Deserialize tensor from zlib compressed binary string -}
 fromBinary :: (
-    Serialize a
+    Serialize a, Unboxed.Unbox a
   ) => ByteString.ByteString    -- ^ ByteString to deserialize
     -> Either String (Tensor a) -- ^ Deserialized tensor or an error message. 
 fromBinary = Data.Serialize.decodeLazy . decompress
 
 {-| Read tensor from binary file -}
 fromBinaryFile :: (
-    Serialize a
+    Serialize a, Unboxed.Unbox a
   ) => String                       -- ^ File path. 
     -> ExceptT String IO (Tensor a) -- ^ Deserialized tensor or an error message
 fromBinaryFile fileName = do
@@ -96,14 +95,14 @@ 
 {-| Serialize tensor to JSON string -}
 toJSON :: (
-    ToJSON a
+    ToJSON a, Unboxed.Unbox a
   ) => Tensor a              -- ^ Tensor to serialize. 
     -> ByteString.ByteString -- ^ Tensor serialized to lazy ByteString. 
 toJSON = Data.Aeson.encode
 
 {-| Write tensor to JSON file -}
 toJSONFile :: (
-    ToJSON a
+    ToJSON a, Unboxed.Unbox a
   ) => Tensor a -- ^ Tensor to serialize
     -> String   -- ^ File path. 
     -> IO ()
@@ -114,14 +113,14 @@ 
 {-| Deserialize tensor from JSON string -}
 fromJSON :: (
-    FromJSON a
+    FromJSON a, Unboxed.Unbox a
   ) => ByteString.ByteString -- ^ ByteString to deserialize
     -> Maybe (Tensor a)      -- ^ Deserialized tensor or Nothing, if deserialization error occured. 
 fromJSON = Data.Aeson.decode
 
 {-| Read tensor from JSON file -}
 fromJSONFile :: (
-    FromJSON a
+    FromJSON a, Unboxed.Unbox a
   ) => String               -- ^ File path. 
     -> MaybeT IO (Tensor a) -- ^ Deserialized tensor or Nothing, if error occured. 
 fromJSONFile fileName = do
@@ -131,25 +130,35 @@ 
 {-| Write tensor to CSV file -}
 toCSVFile :: (
-  ToField a
+  ToField a, Unboxed.Unbox a
   ) => Tensor a -- ^ Tensor to serialize
     -> String   -- ^ File path
     -> IO ()
-toCSVFile (FiniteTensor _ vrows) fileName = do
-  let rows = Boxed.toList vrows
-  let bs = Data.Csv.encode rows
+
+-- Encoding Scalar value
+toCSVFile s@(Scalar _) fileName = do
+  let bs = Data.Csv.encode [s]
   runConduitRes $ 
     sourceLazy bs .| sinkFile fileName
+
+-- Encoding SimpleFinite (1D) tensor
 toCSVFile (SimpleFinite _ vs) fileName = do
   let rows = [vs]
   let bs = Data.Csv.encode rows
   runConduitRes $ 
     sourceLazy bs .| sinkFile fileName
 
+-- Encoding FiniteTensor (many dimensions)
+toCSVFile (FiniteTensor _ vrows) fileName = do
+  let rows = Boxed.toList vrows
+  let bs = Data.Csv.encode rows
+  runConduitRes $ 
+    sourceLazy bs .| sinkFile fileName
 
+
 {-| Read tensor from CSV -}
 fromCSVFile :: (
-  FromField a
+  FromField a, Unboxed.Unbox a
   ) => String -- ^ File path. 
     -> Char   -- ^ CSV separator
     -> String -- ^ Matrix indices names
@@ -158,13 +167,13 @@   --let csvSettings = CSVSettings separator Nothing
   contents <- lift $ runConduitRes $ 
     sourceFile fileName .| sinkLazy
-  let decodedData = Data.Csv.decodeWith (DecodeOptions (BS.c2w separator)) NoHeader contents :: FromField a => Either String (Boxed.Vector (Boxed.Vector a))
+  let decodedData = Data.Csv.decodeWith (DecodeOptions (BS.c2w separator)) NoHeader contents :: (FromField a, Unboxed.Unbox a) => Either String (Boxed.Vector (Unboxed.Vector a))
   if isLeft decodedData 
   then do
     let msg = fromLeft "" decodedData
     ExceptT $ return $ Left msg
   else do
-    let components = fromRight (Boxed.empty) decodedData
-    let rows = (\r -> SimpleFinite (Finite.Covariant (Boxed.length r) [covI]) r) <$> components
+    let components = fromRight Boxed.empty decodedData
+    let rows = (\r -> SimpleFinite (Finite.Covariant (Unboxed.length r) [covI]) r) <$> components
     ExceptT $ return $ Right $ FiniteTensor (Finite.Contravariant (Boxed.length rows) [conI]) rows 
 fromCSVFile _ _ _ = error "You must provide exactly two indices names!"
test/binary/Spec.hs view
@@ -16,7 +16,7 @@ fileName1  = "test/m1"
 
 m1 :: Tensor Double
-m1 = Matrix.fromIndices "ij" 500 500 $ \i j -> cos (fromIntegral i) + sin (fromIntegral j)
+m1 = Matrix.fromIndices "ij" 50 50 $ \i j -> cos (fromIntegral i) + sin (fromIntegral j)
 
 writeMatrixBinary :: Tensor Double -> String -> IO ()
 writeMatrixBinary m fileName = do
test/csv/Spec.hs view
@@ -16,7 +16,7 @@ fileName1  = "test/m1"
 
 m1 :: Tensor Double
-m1 = Matrix.fromIndices "ij" 500 500 $ \i j -> cos (fromIntegral i) + sin (fromIntegral j)
+m1 = Matrix.fromIndices "ij" 50 50 $ \i j -> cos (fromIntegral i) + sin (fromIntegral j)
 
 writeMatrixCSV :: Tensor Double -> String -> IO ()
 writeMatrixCSV m fileName = do
test/json/Spec.hs view
@@ -16,7 +16,7 @@ fileName1  = "test/m1"
 
 m1 :: Tensor Double
-m1 = Matrix.fromIndices "ij" 500 500 $ \i j -> cos (fromIntegral i) + sin (fromIntegral j)
+m1 = Matrix.fromIndices "ij" 50 50 $ \i j -> cos (fromIntegral i) + sin (fromIntegral j)
 
 writeMatrixJSON :: Tensor Double -> String -> IO ()
 writeMatrixJSON m fileName = do