packages feed

multilinear 0.4.0.0 → 0.5.0.0

raw patch · 8 files changed

+120/−133 lines, 8 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Multilinear.Generic.MultiCore: _map :: (Unbox a, Unbox b, NFData b) => (a -> b) -> Tensor a -> Tensor b
- Multilinear.Generic.MultiCore: _standardize :: Unbox a => Tensor a -> Tensor a
- Multilinear.Generic.MultiCore: instance (Data.Vector.Unboxed.Base.Unbox a, GHC.Float.Floating a, Control.DeepSeq.NFData a) => GHC.Float.Floating (Multilinear.Generic.MultiCore.Tensor a)
- Multilinear.Generic.MultiCore: instance (Data.Vector.Unboxed.Base.Unbox a, GHC.Num.Num a, Control.DeepSeq.NFData a) => GHC.Num.Num (Multilinear.Generic.MultiCore.Tensor a)
- Multilinear.Generic.MultiCore: instance (Data.Vector.Unboxed.Base.Unbox a, GHC.Real.Fractional a, Control.DeepSeq.NFData a) => GHC.Real.Fractional (Multilinear.Generic.MultiCore.Tensor a)
- Multilinear.Generic.MultiCore: instance (Data.Vector.Unboxed.Base.Unbox a, GHC.Show.Show a) => GHC.Show.Show (Multilinear.Generic.MultiCore.Tensor a)
- Multilinear.Generic.MultiCore: instance Data.Vector.Unboxed.Base.Unbox a => Multilinear.Class.Multilinear Multilinear.Generic.MultiCore.Tensor a
- Multilinear.Generic.Sequential: _map :: (Unbox a, Unbox b) => (a -> b) -> Tensor a -> Tensor b
- Multilinear.Generic.Sequential: _standardize :: Unbox a => Tensor a -> Tensor a
- Multilinear.Generic.Sequential: instance (Data.Vector.Unboxed.Base.Unbox a, GHC.Float.Floating a, Control.DeepSeq.NFData a) => GHC.Float.Floating (Multilinear.Generic.Sequential.Tensor a)
- Multilinear.Generic.Sequential: instance (Data.Vector.Unboxed.Base.Unbox a, GHC.Num.Num a, Control.DeepSeq.NFData a) => GHC.Num.Num (Multilinear.Generic.Sequential.Tensor a)
- Multilinear.Generic.Sequential: instance (Data.Vector.Unboxed.Base.Unbox a, GHC.Real.Fractional a, Control.DeepSeq.NFData a) => GHC.Real.Fractional (Multilinear.Generic.Sequential.Tensor a)
- Multilinear.Generic.Sequential: instance (Data.Vector.Unboxed.Base.Unbox a, GHC.Show.Show a) => GHC.Show.Show (Multilinear.Generic.Sequential.Tensor a)
- Multilinear.Generic.Sequential: instance Data.Vector.Unboxed.Base.Unbox a => Multilinear.Class.Multilinear Multilinear.Generic.Sequential.Tensor a
+ Multilinear.Class: standardize :: Multilinear t a => t a -> t a
+ Multilinear.Generic: toMultiCore :: Tensor a -> Tensor a
+ Multilinear.Generic: toSequential :: Tensor a -> Tensor a
+ Multilinear.Generic.MultiCore: instance (Control.DeepSeq.NFData a, Data.Vector.Unboxed.Base.Unbox a) => Multilinear.Class.Multilinear Multilinear.Generic.MultiCore.Tensor a
+ Multilinear.Generic.MultiCore: instance (GHC.Float.Floating a, Multilinear.Class.Multilinear Multilinear.Generic.MultiCore.Tensor a) => GHC.Float.Floating (Multilinear.Generic.MultiCore.Tensor a)
+ Multilinear.Generic.MultiCore: instance (GHC.Num.Num a, Multilinear.Class.Multilinear Multilinear.Generic.MultiCore.Tensor a) => GHC.Num.Num (Multilinear.Generic.MultiCore.Tensor a)
+ Multilinear.Generic.MultiCore: instance (GHC.Real.Fractional a, Multilinear.Class.Multilinear Multilinear.Generic.MultiCore.Tensor a) => GHC.Real.Fractional (Multilinear.Generic.MultiCore.Tensor a)
+ Multilinear.Generic.MultiCore: instance (Multilinear.Class.Multilinear Multilinear.Generic.MultiCore.Tensor a, GHC.Show.Show a) => GHC.Show.Show (Multilinear.Generic.MultiCore.Tensor a)
+ Multilinear.Generic.Sequential: instance (Control.DeepSeq.NFData a, Data.Vector.Unboxed.Base.Unbox a) => Multilinear.Class.Multilinear Multilinear.Generic.Sequential.Tensor a
+ Multilinear.Generic.Sequential: instance (GHC.Float.Floating a, Multilinear.Class.Multilinear Multilinear.Generic.Sequential.Tensor a) => GHC.Float.Floating (Multilinear.Generic.Sequential.Tensor a)
+ Multilinear.Generic.Sequential: instance (GHC.Real.Fractional a, Multilinear.Class.Multilinear Multilinear.Generic.Sequential.Tensor a) => GHC.Real.Fractional (Multilinear.Generic.Sequential.Tensor a)
+ Multilinear.Generic.Sequential: instance (Multilinear.Class.Multilinear Multilinear.Generic.Sequential.Tensor a, GHC.Num.Num a) => GHC.Num.Num (Multilinear.Generic.Sequential.Tensor a)
+ Multilinear.Generic.Sequential: instance (Multilinear.Class.Multilinear Multilinear.Generic.Sequential.Tensor a, GHC.Show.Show a) => GHC.Show.Show (Multilinear.Generic.Sequential.Tensor a)
- Multilinear.Class: class (Unbox a) => Multilinear t a
+ Multilinear.Class: class (Generic (t a), NFData a, NFData (t a), Unbox a) => Multilinear t a
- Multilinear.Generic.MultiCore: (+.) :: (Unbox a, Num a, NFData a) => a -> Tensor a -> Tensor a
+ Multilinear.Generic.MultiCore: (+.) :: (Num a, Multilinear Tensor a) => a -> Tensor a -> Tensor a
- Multilinear.Generic.MultiCore: (-.) :: (Unbox a, Num a, NFData a) => a -> Tensor a -> Tensor a
+ Multilinear.Generic.MultiCore: (-.) :: (Num a, Multilinear Tensor a) => a -> Tensor a -> Tensor a
- Multilinear.Generic.MultiCore: (.*) :: (Unbox a, Num a, NFData a) => Tensor a -> a -> Tensor a
+ Multilinear.Generic.MultiCore: (.*) :: (Num a, Multilinear Tensor a) => Tensor a -> a -> Tensor a
- Multilinear.Generic.MultiCore: (.+) :: (Unbox a, Num a, NFData a) => Tensor a -> a -> Tensor a
+ Multilinear.Generic.MultiCore: (.+) :: (Num a, Multilinear Tensor a) => Tensor a -> a -> Tensor a
- Multilinear.Generic.MultiCore: (.-) :: (Unbox a, Num a, NFData a) => Tensor a -> a -> Tensor a
+ Multilinear.Generic.MultiCore: (.-) :: (Num a, Multilinear Tensor a) => Tensor a -> a -> Tensor a
- Multilinear.Generic.MultiCore: _elemByElem :: (Num a, Unbox a, NFData a) => Tensor a -> Tensor a -> (a -> a -> a) -> (Tensor a -> Tensor a -> Tensor a) -> Tensor a
+ Multilinear.Generic.MultiCore: _elemByElem :: (Num a, Multilinear Tensor a) => Tensor a -> Tensor a -> (a -> a -> a) -> (Tensor a -> Tensor a -> Tensor a) -> Tensor a
- Multilinear.Generic.MultiCore: filter :: Unbox a => (String -> Int -> Bool) -> Tensor a -> Tensor a
+ Multilinear.Generic.MultiCore: filter :: Multilinear Tensor a => (String -> Int -> Bool) -> Tensor a -> Tensor a
- Multilinear.Generic.MultiCore: filterIndex :: Unbox a => String -> (Int -> Bool) -> Tensor a -> Tensor a
+ Multilinear.Generic.MultiCore: filterIndex :: Multilinear Tensor a => String -> (Int -> Bool) -> Tensor a -> Tensor a
- Multilinear.Generic.MultiCore: map :: (Unbox a, Unbox b, NFData b) => (a -> b) -> Tensor a -> Tensor b
+ Multilinear.Generic.MultiCore: map :: (Multilinear Tensor a, Multilinear Tensor b) => (a -> b) -> Tensor a -> Tensor b
- Multilinear.Generic.MultiCore: zipT :: (Num a, NFData a, Unbox a) => (a -> a -> a) -> Tensor a -> Tensor a -> Tensor a
+ Multilinear.Generic.MultiCore: zipT :: (Num a, Multilinear Tensor a) => (a -> a -> a) -> Tensor a -> Tensor a -> Tensor a
- Multilinear.Generic.MultiCore: zipWith :: (Unbox a, Unbox b, Unbox c, NFData c) => (a -> b -> c) -> Tensor a -> Tensor b -> Tensor c
+ Multilinear.Generic.MultiCore: zipWith :: (Multilinear Tensor a, Multilinear Tensor b, Multilinear Tensor c) => (a -> b -> c) -> Tensor a -> Tensor b -> Tensor c
- Multilinear.Generic.Sequential: (*.) :: (Unbox a, Num a) => a -> Tensor a -> Tensor a
+ Multilinear.Generic.Sequential: (*.) :: (Num a, Multilinear Tensor a) => a -> Tensor a -> Tensor a
- Multilinear.Generic.Sequential: (+.) :: (Unbox a, Num a) => a -> Tensor a -> Tensor a
+ Multilinear.Generic.Sequential: (+.) :: (Num a, Multilinear Tensor a) => a -> Tensor a -> Tensor a
- Multilinear.Generic.Sequential: (-.) :: (Unbox a, Num a) => a -> Tensor a -> Tensor a
+ Multilinear.Generic.Sequential: (-.) :: (Num a, Multilinear Tensor a) => a -> Tensor a -> Tensor a
- Multilinear.Generic.Sequential: (.*) :: (Unbox a, Num a) => Tensor a -> a -> Tensor a
+ Multilinear.Generic.Sequential: (.*) :: (Num a, Multilinear Tensor a) => Tensor a -> a -> Tensor a
- Multilinear.Generic.Sequential: (.+) :: (Unbox a, Num a) => Tensor a -> a -> Tensor a
+ Multilinear.Generic.Sequential: (.+) :: (Num a, Multilinear Tensor a) => Tensor a -> a -> Tensor a
- Multilinear.Generic.Sequential: (.-) :: (Unbox a, Num a) => Tensor a -> a -> Tensor a
+ Multilinear.Generic.Sequential: (.-) :: (Num a, Multilinear Tensor a) => Tensor a -> a -> Tensor a
- Multilinear.Generic.Sequential: _elemByElem :: (Num a, Unbox a, NFData a) => Tensor a -> Tensor a -> (a -> a -> a) -> (Tensor a -> Tensor a -> Tensor a) -> Tensor a
+ Multilinear.Generic.Sequential: _elemByElem :: (Num a, Multilinear Tensor a) => Tensor a -> Tensor a -> (a -> a -> a) -> (Tensor a -> Tensor a -> Tensor a) -> Tensor a
- Multilinear.Generic.Sequential: filter :: Unbox a => (String -> Int -> Bool) -> Tensor a -> Tensor a
+ Multilinear.Generic.Sequential: filter :: Multilinear Tensor a => (String -> Int -> Bool) -> Tensor a -> Tensor a
- Multilinear.Generic.Sequential: filterIndex :: Unbox a => String -> (Int -> Bool) -> Tensor a -> Tensor a
+ Multilinear.Generic.Sequential: filterIndex :: Multilinear Tensor a => String -> (Int -> Bool) -> Tensor a -> Tensor a
- Multilinear.Generic.Sequential: map :: (Unbox a, Unbox b) => (a -> b) -> Tensor a -> Tensor b
+ Multilinear.Generic.Sequential: map :: (Multilinear Tensor a, Multilinear Tensor b) => (a -> b) -> Tensor a -> Tensor b
- Multilinear.Generic.Sequential: zipT :: (Num a, NFData a, Unbox a) => (a -> a -> a) -> Tensor a -> Tensor a -> Tensor a
+ Multilinear.Generic.Sequential: zipT :: (Num a, Multilinear Tensor a) => (a -> a -> a) -> Tensor a -> Tensor a -> Tensor a
- Multilinear.Generic.Sequential: zipWith :: (Unbox a, Unbox b, Unbox c) => (a -> b -> c) -> Tensor a -> Tensor b -> Tensor c
+ Multilinear.Generic.Sequential: zipWith :: (Multilinear Tensor a, Multilinear Tensor b, Multilinear Tensor c) => (a -> b -> c) -> Tensor a -> Tensor b -> Tensor c

Files

ChangeLog.md view
@@ -1,3 +1,7 @@+# 0.5.0.0, 2018-11-25
+- reformulation of Multilinear class - added Generic and NFData superclasses. This allows any Multilinear tensor to be derived generically in e.g. serialization instances and also fully evaluated for performace reasons
+- added simple Sequential <=> MultiCore converters in Multilinear.Generic module
+
 # 0.4.0.0, 2018-11-24
 - added multi-core parallelism, sample benchmark is available in ./benchmark/results.zip
 - more robust QuickCheck tests
multilinear.cabal view
@@ -2,10 +2,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 033c8dbef9eab24df7b3396f684551d557968e2a8963865f404a7ca247732d7d+-- hash: 270ef768912c7c25c99a825bb179051c9389d6a254559adb76cceff3d7e9c203  name:           multilinear-version:        0.4.0.0+version:        0.5.0.0 synopsis:       Comprehensive and efficient (multi)linear algebra implementation. description:    Comprehensive and efficient (multi)linear algebra implementation, based on generic tensor formalism and concise Ricci-Curbastro index syntax. More information available on GitHub: <https://github.com/ArturB/multilinear#readme> category:       Machine learning@@ -45,7 +45,7 @@       Paths_multilinear   hs-source-dirs:       src-  default-extensions: DeriveGeneric FlexibleContexts FlexibleInstances GADTs GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses ScopedTypeVariables StandaloneDeriving+  default-extensions: DeriveGeneric FlexibleContexts FlexibleInstances GADTs GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses ScopedTypeVariables StandaloneDeriving UndecidableInstances   ghc-options: -O2 -W   build-depends:       base >=4.7 && <5@@ -63,7 +63,7 @@       Paths_multilinear   hs-source-dirs:       test/multicore-  default-extensions: DeriveGeneric FlexibleContexts FlexibleInstances GADTs GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses ScopedTypeVariables StandaloneDeriving+  default-extensions: DeriveGeneric FlexibleContexts FlexibleInstances GADTs GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses ScopedTypeVariables StandaloneDeriving UndecidableInstances   ghc-options: -O2 -W -threaded -rtsopts -with-rtsopts=-N   build-depends:       QuickCheck@@ -83,7 +83,7 @@       Paths_multilinear   hs-source-dirs:       test/sequential-  default-extensions: DeriveGeneric FlexibleContexts FlexibleInstances GADTs GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses ScopedTypeVariables StandaloneDeriving+  default-extensions: DeriveGeneric FlexibleContexts FlexibleInstances GADTs GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses ScopedTypeVariables StandaloneDeriving UndecidableInstances   ghc-options: -O2 -W -threaded -rtsopts -with-rtsopts=-N   build-depends:       QuickCheck@@ -102,7 +102,7 @@       Paths_multilinear   hs-source-dirs:       benchmark/multicore/memory-  default-extensions: DeriveGeneric FlexibleContexts FlexibleInstances GADTs GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses ScopedTypeVariables StandaloneDeriving+  default-extensions: DeriveGeneric FlexibleContexts FlexibleInstances GADTs GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses ScopedTypeVariables StandaloneDeriving UndecidableInstances   ghc-options: -O2 -W -threaded -rtsopts -with-rtsopts=-N   build-depends:       base >=4.7 && <5@@ -117,7 +117,7 @@       Paths_multilinear   hs-source-dirs:       benchmark/multicore/profile-  default-extensions: DeriveGeneric FlexibleContexts FlexibleInstances GADTs GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses ScopedTypeVariables StandaloneDeriving+  default-extensions: DeriveGeneric FlexibleContexts FlexibleInstances GADTs GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses ScopedTypeVariables StandaloneDeriving UndecidableInstances   ghc-options: -O2 -W -threaded -rtsopts -with-rtsopts=-N   build-depends:       base >=4.7 && <5@@ -132,7 +132,7 @@       Paths_multilinear   hs-source-dirs:       benchmark/multicore/time-  default-extensions: DeriveGeneric FlexibleContexts FlexibleInstances GADTs GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses ScopedTypeVariables StandaloneDeriving+  default-extensions: DeriveGeneric FlexibleContexts FlexibleInstances GADTs GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses ScopedTypeVariables StandaloneDeriving UndecidableInstances   ghc-options: -O2 -W -threaded -rtsopts -with-rtsopts=-N   build-depends:       base >=4.7 && <5@@ -147,7 +147,7 @@       Paths_multilinear   hs-source-dirs:       benchmark/sequential/memory-  default-extensions: DeriveGeneric FlexibleContexts FlexibleInstances GADTs GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses ScopedTypeVariables StandaloneDeriving+  default-extensions: DeriveGeneric FlexibleContexts FlexibleInstances GADTs GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses ScopedTypeVariables StandaloneDeriving UndecidableInstances   ghc-options: -O2 -W   build-depends:       base >=4.7 && <5@@ -162,7 +162,7 @@       Paths_multilinear   hs-source-dirs:       benchmark/sequential/profile-  default-extensions: DeriveGeneric FlexibleContexts FlexibleInstances GADTs GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses ScopedTypeVariables StandaloneDeriving+  default-extensions: DeriveGeneric FlexibleContexts FlexibleInstances GADTs GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses ScopedTypeVariables StandaloneDeriving UndecidableInstances   ghc-options: -O2 -W   build-depends:       base >=4.7 && <5@@ -177,7 +177,7 @@       Paths_multilinear   hs-source-dirs:       benchmark/sequential/time-  default-extensions: DeriveGeneric FlexibleContexts FlexibleInstances GADTs GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses ScopedTypeVariables StandaloneDeriving+  default-extensions: DeriveGeneric FlexibleContexts FlexibleInstances GADTs GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses ScopedTypeVariables StandaloneDeriving UndecidableInstances   ghc-options: -O2 -W   build-depends:       base >=4.7 && <5
src/Multilinear.hs view
@@ -143,11 +143,9 @@ 
 module Multilinear (
     module Multilinear.Class,
-    module Multilinear.Generic,
-    module Multilinear.Generic.Sequential
+    module Multilinear.Generic
 ) where
 
 -- Re-export basic library modules
 import           Multilinear.Class
 import           Multilinear.Generic
-import           Multilinear.Generic.Sequential
src/Multilinear/Class.hs view
@@ -98,7 +98,6 @@    | [k:4] [3,4,5,6]
    | [k:4] [4,5,6,7]
 >>> m1 * m2
-
 \<i:3\>
    | [k:4] [30,40,50,60]
    | [k:4] [40,50,60,70]
@@ -146,14 +145,23 @@     Multilinear(..)
 ) where
 
+import           Control.DeepSeq
 import           Data.Maybe
 import           Data.Set
 import qualified Data.Vector.Unboxed as Unboxed
+import           GHC.Generics
 import           Multilinear.Index
 
-{-| Multidimensional array treated as multilinear map - tensor -}
+{-| Multidimensional array treated as multilinear map - tensor 
+    Superclasses:
+     - Generic (t a) - enforce Generic instance, allowing to derive e.g. serialization instances for any tensor
+     - NFData a, NFData (t a) - for performance reasons, every tensor should be able to be fully evaluated
+     - Unboxed.Unbox a - for performance reasons, every tensor should be implemented using Vector.Unboxed
+ -}
 class (
-  Unboxed.Unbox a
+   Generic (t a),          
+   NFData a, NFData (t a), 
+   Unboxed.Unbox a         
   ) => Multilinear t a where
 
     {-| Generic tensor constructor, using combinator function on its indices -}
@@ -311,3 +319,6 @@     infixl 6 <<<|
     (<<<|) :: t a -> String -> t a
     t <<<| n = shiftLeftmost t n
+
+    -- | Move covariant indices to deeper recursion level
+    standardize :: t a -> t a
src/Multilinear/Generic.hs view
@@ -1,6 +1,6 @@ {-|
 Module      : Multilinear.Generic
-Description : Re-export default tensor implementation
+Description : Re-export default tensor implementation and provides simple tensor converters
 Copyright   : (c) Artur M. Brodzki, 2018
 License     : BSD3
 Maintainer  : artur@brodzki.org
@@ -10,7 +10,23 @@ -}
 
 module Multilinear.Generic (
-    module DefaultTensorImplementation
+    module Multilinear.Generic.Sequential,
+    toMultiCore, toSequential
 ) where
 
-import Multilinear.Generic.Sequential as DefaultTensorImplementation
+import           Data.Vector                    as Boxed
+import           Multilinear.Generic.Sequential
+import qualified Multilinear.Generic.Sequential as Sequential
+import qualified Multilinear.Generic.MultiCore  as MultiCore
+
+-- | Convert Sequential tensor to MultiCore
+toMultiCore :: Sequential.Tensor a -> MultiCore.Tensor a
+toMultiCore (Sequential.Scalar x) = MultiCore.Scalar x
+toMultiCore (Sequential.SimpleFinite i ts) = MultiCore.SimpleFinite i ts
+toMultiCore (Sequential.FiniteTensor i ts) = MultiCore.FiniteTensor i $ Boxed.map toMultiCore ts
+
+-- | Convert MultiCore tensor to Sequential
+toSequential :: MultiCore.Tensor a -> Sequential.Tensor a
+toSequential (MultiCore.Scalar x) = Sequential.Scalar x
+toSequential (MultiCore.SimpleFinite i ts) = Sequential.SimpleFinite i ts
+toSequential (MultiCore.FiniteTensor i ts) = Sequential.FiniteTensor i $ Boxed.map toSequential ts
src/Multilinear/Generic/MultiCore.hs view
@@ -14,8 +14,8 @@     Tensor(..), 
     -- * Auxiliary functions
     (!), isScalar, isSimple, isFiniteTensor,
-    tensorIndex, _standardize, _mergeScalars, 
-    _map, _contractedIndices, _elemByElem, zipT,
+    tensorIndex, _mergeScalars, 
+    _contractedIndices, _elemByElem, zipT,
     -- * Additional functions
     (.+), (.-), (.*), (+.), (-.), (*.),
     Multilinear.Generic.MultiCore.map, 
@@ -124,18 +124,13 @@ -- | NFData instance
 instance NFData a => NFData (Tensor a)
 
--- | Move contravariant indices to lower recursion level
-{-# INLINE _standardize #-}
-_standardize :: (Unboxed.Unbox a) => Tensor a -> Tensor a
-_standardize tens = foldl' (<<<|) tens $ Index.indexName <$> (Index.isContravariant `Prelude.filter` indices tens)
-
 -- | Print tensor
 instance (
-    Unboxed.Unbox a, Show a
+    Multilinear Tensor a, Show a
     ) => Show (Tensor a) where
 
     -- merge errors first and then print whole tensor
-    show = show' . _standardize
+    show = show' . standardize
         where
         show' x = case x of
             -- Scalar is showed simply as its value
@@ -162,23 +157,6 @@         _        -> FiniteTensor index1 $ _mergeScalars <$> ts1
     _ -> x
 
--- | Generic map function, which does not require a,b types to be Num
-_map :: (
-    Unboxed.Unbox a, Unboxed.Unbox b, NFData b
-    ) => (a -> b)
-      -> Tensor a
-      -> Tensor b
-_map f x = case x of
-    -- Mapping scalar simply maps its value
-    Scalar v                -> Scalar $ f v
-    -- Mapping complex tensor does mapping element by element
-    SimpleFinite index ts   -> SimpleFinite index (f `Unboxed.map` ts)
-    FiniteTensor index ts   -> 
-        let len = Boxed.length ts
-            lts = Boxed.toList $ _map f <$> ts
-            ltsp = lts `Parallel.using` Parallel.parListChunk (len `div` 8) Parallel.rdeepseq
-        in  FiniteTensor index $ Boxed.fromList ltsp
-
 {-| Transpose Vector of Vectors, analogous to Data.List.transpose function. It is assumed, that all vectors on deeper recursion level have the same length.  -}
 _transpose :: Boxed.Vector (Boxed.Vector a)  -- ^ Vector of vectors to transpose
            -> Boxed.Vector (Boxed.Vector a)
@@ -204,7 +182,7 @@ 
 {-| Apply a tensor operator (here denoted by (+) ) elem by elem, trying to connect as many common indices as possible -}
 {-# INLINE _elemByElem' #-}
-_elemByElem' :: (Num a, Unboxed.Unbox a, NFData a)
+_elemByElem' :: (Num a, Multilinear Tensor a)
              => Tensor a                            -- ^ First argument of operator
              -> Tensor a                            -- ^ Second argument of operator
              -> (a -> a -> a)                       -- ^ Operator on tensor elements if indices are different
@@ -253,7 +231,7 @@ 
 {-| Apply a tensor operator elem by elem and merge scalars to simple tensor at the and -}
 {-# INLINE _elemByElem #-}
-_elemByElem :: (Num a, Unboxed.Unbox a, NFData a)
+_elemByElem :: (Num a, Multilinear Tensor a)
             => Tensor a                             -- ^ First argument of operator
             -> Tensor a                             -- ^ Second argument of operator
             -> (a -> a -> a)                        -- ^ Operator on tensor elements if indices are different
@@ -271,7 +249,7 @@ -- | Zipping two tensors with a combinator, assuming they have the same indices. 
 {-# INLINE zipT #-}
 zipT :: (
-    Num a, NFData a, Unboxed.Unbox a
+    Num a, Multilinear Tensor a
     ) => (a -> a -> a)                        -- ^ The zipping combinator
       -> Tensor a                             -- ^ First tensor to zip
       -> Tensor a                             -- ^ Second tensor to zip
@@ -293,7 +271,7 @@ 
 -- | dot product of two tensors
 {-# INLINE dot #-}
-dot :: (Num a, Unboxed.Unbox a, NFData a)
+dot :: (Num a, Multilinear Tensor a)
       => Tensor a  -- ^ First dot product argument
       -> Tensor a  -- ^ Second dot product argument
       -> Tensor a  -- ^ Resulting dot product
@@ -347,9 +325,8 @@     " - index1 is " ++ show i1' ++
     " and index2 is " ++ show i2'
 
-
 -- | Tensors can be added, subtracted and multiplicated
-instance (Unboxed.Unbox a, Num a, NFData a) => Num (Tensor a) where
+instance (Num a, Multilinear Tensor a) => Num (Tensor a) where
 
     -- Adding - element by element
     {-# INLINE (+) #-}
@@ -377,7 +354,7 @@     fromInteger x = Scalar $ fromInteger x
 
 -- | Tensors can be divided by each other
-instance (Unboxed.Unbox a, Fractional a, NFData a) => Fractional (Tensor a) where
+instance (Fractional a, Multilinear Tensor a) => Fractional (Tensor a) where
     -- Tensor dividing: TODO
     {-# INLINE (/) #-}
     _ / _ = error "TODO"
@@ -389,7 +366,7 @@ -- Real-number functions on tensors.
 -- Function of tensor is tensor of function of its elements
 -- E.g. exp [1,2,3,4] = [exp 1, exp2, exp3, exp4]
-instance (Unboxed.Unbox a, Floating a, NFData a) => Floating (Tensor a) where
+instance (Floating a, Multilinear Tensor a) => Floating (Tensor a) where
 
     {-| PI number -}
     {-# INLINE pi #-}
@@ -444,7 +421,7 @@     atanh t = atanh `Multilinear.Generic.MultiCore.map` t
 
 -- Multilinear operations
-instance (Unboxed.Unbox a) => Multilinear Tensor a where
+instance (NFData a, Unboxed.Unbox a) => Multilinear Tensor a where
     -- Generic tensor constructor
     -- If only one upper index is given, generate a SimpleFinite tensor with upper index
     fromIndices [u] [] [s] [] f = 
@@ -608,11 +585,14 @@             in  _mergeScalars result
         -- there is only one index and therefore it cannot be shifted
         | otherwise = t1
+    
+    -- | Move contravariant indices to lower recursion level
+    standardize tens = foldl' (<<<|) tens $ Index.indexName <$> (Index.isContravariant `Prelude.filter` indices tens)
 
 -- Add scalar right
 {-# INLINE (.+) #-}
 (.+) :: (
-    Unboxed.Unbox a, Num a, NFData a
+    Num a, Multilinear Tensor a
     ) => Tensor a 
       -> a 
       -> Tensor a
@@ -621,7 +601,7 @@ -- Subtract scalar right
 {-# INLINE (.-) #-}
 (.-) :: (
-    Unboxed.Unbox a, Num a, NFData a
+    Num a, Multilinear Tensor a
     ) => Tensor a 
       -> a 
       -> Tensor a
@@ -630,7 +610,7 @@ -- Multiplicate by scalar right
 {-# INLINE (.*) #-}
 (.*) :: (
-    Unboxed.Unbox a, Num a, NFData a
+    Num a, Multilinear Tensor a
     ) => Tensor a 
       -> a 
       -> Tensor a
@@ -639,7 +619,7 @@ -- Add scalar left
 {-# INLINE (+.) #-}
 (+.) :: (
-    Unboxed.Unbox a, Num a, NFData a
+    Num a, Multilinear Tensor a
     ) => a 
       -> Tensor a 
       -> Tensor a
@@ -648,7 +628,7 @@ -- Subtract scalar left
 {-# INLINE (-.) #-}
 (-.) :: (
-    Unboxed.Unbox a, Num a, NFData a
+    Num a, Multilinear Tensor a
     ) => a 
       -> Tensor a 
       -> Tensor a
@@ -663,14 +643,11 @@       -> Tensor a
 x *. t = (x*) `Multilinear.Generic.MultiCore.map` t
 
-    
-{-| Simple mapping -}
-{-| @map f t@ returns tensor @t2@ in which @t2[i1,i2,...] = f t[i1,i2,...]@ -}
-{-# INLINE map #-}
+-- | Simple mapping
 map :: (
-    Unboxed.Unbox a, Unboxed.Unbox b, NFData b
-    ) => (a -> b) 
-      -> Tensor a 
+    Multilinear Tensor a, Multilinear Tensor b
+    ) => (a -> b)
+      -> Tensor a
       -> Tensor b
 map f x = case x of
     -- Mapping scalar simply maps its value
@@ -695,7 +672,7 @@     If for some index all elements are removed, the index itself is removed from tensor. -}
 {-# INLINE filter #-}
 filter :: (
-    Unboxed.Unbox a
+    Multilinear Tensor a
     ) => (String -> Int -> Bool) -- ^ filter function
       -> Tensor a                -- ^ tensor to filter
       -> Tensor a
@@ -718,7 +695,7 @@ {-| Filtering one index of tensor. -}
 {-# INLINE filterIndex #-}
 filterIndex :: (
-    Unboxed.Unbox a
+    Multilinear Tensor a
     ) => String        -- ^ Index name to filter
       -> (Int -> Bool) -- ^ filter function
       -> Tensor a      -- ^ tensor to filter
@@ -728,7 +705,7 @@ {-| Zip tensors with binary combinator, assuming they have all indices the same -}
 {-# INLINE zipWith' #-}
 zipWith' :: (
-    Unboxed.Unbox a, Unboxed.Unbox b, Unboxed.Unbox c, NFData c
+    Multilinear Tensor a, Multilinear Tensor b, Multilinear Tensor c
     ) => (a -> b -> c) 
       -> Tensor a 
       -> Tensor b 
@@ -736,9 +713,9 @@ -- Zipping two Scalars simply combines their values 
 zipWith' f (Scalar x1) (Scalar x2) = Scalar $ f x1 x2
 -- zipping complex tensor with scalar 
-zipWith' f t (Scalar x) = (`f` x) `_map` t
+zipWith' f t (Scalar x) = (`f` x) `Multilinear.Generic.MultiCore.map` t
 -- zipping scalar with complex tensor
-zipWith' f (Scalar x) t = (x `f`) `_map` t
+zipWith' f (Scalar x) t = (x `f`) `Multilinear.Generic.MultiCore.map` t
 -- Two simple tensors case
 zipWith' f (SimpleFinite index1 v1) (SimpleFinite index2 v2) = 
     if index1 == index2 then 
@@ -754,12 +731,12 @@ 
 {-# INLINE zipWith #-}
 zipWith :: (
-    Unboxed.Unbox a, Unboxed.Unbox b, Unboxed.Unbox c, NFData c
+    Multilinear Tensor a, Multilinear Tensor b, Multilinear Tensor c
     ) => (a -> b -> c) 
       -> Tensor a 
       -> Tensor b 
       -> Tensor c
 zipWith f t1 t2 = 
-    let t1' = _standardize t1
-        t2' = _standardize t2
+    let t1' = standardize t1
+        t2' = standardize t2
     in  zipWith' f t1' t2'
src/Multilinear/Generic/Sequential.hs view
@@ -14,8 +14,8 @@     Tensor(..), 
     -- * Auxiliary functions
     (!), isScalar, isSimple, isFiniteTensor,
-    tensorIndex, _standardize, _mergeScalars, 
-    _map, _contractedIndices, _elemByElem, zipT,
+    tensorIndex, _mergeScalars, 
+    _contractedIndices, _elemByElem, zipT,
     -- * Additional functions
     (.+), (.-), (.*), (+.), (-.), (*.),
     Multilinear.Generic.Sequential.map, 
@@ -73,6 +73,9 @@     } -> Tensor a
     deriving (Eq, Generic)
 
+-- | NFData instance
+instance NFData a => NFData (Tensor a)
+
 {-| Return true if tensor is a scalar -}
 {-# INLINE isScalar #-}
 isScalar :: Unboxed.Unbox a => Tensor a -> Bool
@@ -120,21 +123,14 @@     SimpleFinite ind ts -> Scalar $ ts Unboxed.! (i `mod` Finite.indexSize ind)
     FiniteTensor ind ts -> ts Boxed.! (i `mod` Finite.indexSize ind)
 
--- | NFData instance
-instance NFData a => NFData (Tensor a)
-
--- | Move contravariant indices to lower recursion level
-{-# INLINE _standardize #-}
-_standardize :: (Unboxed.Unbox a) => Tensor a -> Tensor a
-_standardize tens = foldl' (<<<|) tens $ Index.indexName <$> (Index.isContravariant `Prelude.filter` indices tens)
-
 -- | Print tensor
+-- | Assumes tensor is already in Multilinear class, because standardize function
 instance (
-    Unboxed.Unbox a, Show a
+    Multilinear Tensor a, Show a
     ) => Show (Tensor a) where
 
     -- merge errors first and then print whole tensor
-    show = show' . _standardize
+    show = show' . standardize
         where
         show' x = case x of
             -- Scalar is showed simply as its value
@@ -161,19 +157,6 @@         _        -> FiniteTensor index1 $ _mergeScalars <$> ts1
     _ -> x
 
--- | Generic map function, which does not require a,b types to be Num
-_map :: (
-    Unboxed.Unbox a, Unboxed.Unbox b
-    ) => (a -> b)
-      -> Tensor a
-      -> Tensor b
-_map f x = case x of
-    -- Mapping scalar simply maps its value
-    Scalar v                -> Scalar $ f v
-    -- Mapping complex tensor does mapping element by element
-    SimpleFinite index ts   -> SimpleFinite index (f `Unboxed.map` ts)
-    FiniteTensor index ts   -> FiniteTensor index $ _map f <$> ts
-
 {-| Transpose Vector of Vectors, analogous to Data.List.transpose function. It is assumed, that all vectors on deeper recursion level have the same length.  -}
 _transpose :: Boxed.Vector (Boxed.Vector a)  -- ^ Vector of vectors to transpose
            -> Boxed.Vector (Boxed.Vector a)
@@ -199,7 +182,7 @@ 
 {-| Apply a tensor operator (here denoted by (+) ) elem by elem, trying to connect as many common indices as possible -}
 {-# INLINE _elemByElem' #-}
-_elemByElem' :: (Num a, Unboxed.Unbox a, NFData a)
+_elemByElem' :: (Num a, Multilinear Tensor a)
              => Tensor a                            -- ^ First argument of operator
              -> Tensor a                            -- ^ Second argument of operator
              -> (a -> a -> a)                       -- ^ Operator on tensor elements if indices are different
@@ -233,7 +216,7 @@ 
 {-| Apply a tensor operator elem by elem and merge scalars to simple tensor at the and -}
 {-# INLINE _elemByElem #-}
-_elemByElem :: (Num a, Unboxed.Unbox a, NFData a)
+_elemByElem :: (Num a, Multilinear Tensor a)
             => Tensor a                             -- ^ First argument of operator
             -> Tensor a                             -- ^ Second argument of operator
             -> (a -> a -> a)                        -- ^ Operator on tensor elements if indices are different
@@ -251,7 +234,7 @@ -- | Zipping two tensors with a combinator, assuming they have the same indices. 
 {-# INLINE zipT #-}
 zipT :: (
-    Num a, NFData a, Unboxed.Unbox a
+    Num a, Multilinear Tensor a
     ) => (a -> a -> a)                        -- ^ The zipping combinator
       -> Tensor a                             -- ^ First tensor to zip
       -> Tensor a                             -- ^ Second tensor to zip
@@ -271,7 +254,7 @@ 
 -- | dot product of two tensors
 {-# INLINE dot #-}
-dot :: (Num a, Unboxed.Unbox a, NFData a)
+dot :: (Num a, Multilinear Tensor a)
       => Tensor a  -- ^ First dot product argument
       -> Tensor a  -- ^ Second dot product argument
       -> Tensor a  -- ^ Resulting dot product
@@ -324,7 +307,7 @@ 
 
 -- | Tensors can be added, subtracted and multiplicated
-instance (Unboxed.Unbox a, Num a, NFData a) => Num (Tensor a) where
+instance (Multilinear Tensor a, Num a) => Num (Tensor a) where
 
     -- Adding - element by element
     {-# INLINE (+) #-}
@@ -352,7 +335,7 @@     fromInteger x = Scalar $ fromInteger x
 
 -- | Tensors can be divided by each other
-instance (Unboxed.Unbox a, Fractional a, NFData a) => Fractional (Tensor a) where
+instance (Fractional a, Multilinear Tensor a) => Fractional (Tensor a) where
     -- Tensor dividing: TODO
     {-# INLINE (/) #-}
     _ / _ = error "TODO"
@@ -364,7 +347,7 @@ -- Real-number functions on tensors.
 -- Function of tensor is tensor of function of its elements
 -- E.g. exp [1,2,3,4] = [exp 1, exp2, exp3, exp4]
-instance (Unboxed.Unbox a, Floating a, NFData a) => Floating (Tensor a) where
+instance (Floating a, Multilinear Tensor a) => Floating (Tensor a) where
 
     {-| PI number -}
     {-# INLINE pi #-}
@@ -419,7 +402,7 @@     atanh t = atanh `Multilinear.Generic.Sequential.map` t
 
 -- Multilinear operations
-instance (Unboxed.Unbox a) => Multilinear Tensor a where
+instance (NFData a, Unboxed.Unbox a) => Multilinear Tensor a where
     -- Generic tensor constructor
     -- If only one upper index is given, generate a SimpleFinite tensor with upper index
     fromIndices [u] [] [s] [] f = 
@@ -546,18 +529,15 @@     {-| Transpose a tensor (switch all indices types) -}
     {-# INLINE transpose #-}
     transpose (Scalar x) = Scalar x
-
     transpose (FiniteTensor (Finite.Covariant count name) ts) =
         FiniteTensor (Finite.Contravariant count name) (Multilinear.transpose <$> ts)
     transpose (FiniteTensor (Finite.Contravariant count name) ts) =
         FiniteTensor (Finite.Covariant count name) (Multilinear.transpose <$> ts)
-
     transpose (SimpleFinite (Finite.Covariant count name) ts) =
         SimpleFinite (Finite.Contravariant count name) ts
     transpose (SimpleFinite (Finite.Contravariant count name) ts) =
         SimpleFinite (Finite.Covariant count name) ts
 
-
     {-| Shift tensor index right -}
     {-| Moves given index one level deeper in recursion -}
     -- Scalar has no indices to shift
@@ -584,10 +564,14 @@         -- there is only one index and therefore it cannot be shifted
         | otherwise = t1
 
+    -- | Move contravariant indices to lower recursion level
+    standardize tens = foldl' (<<<|) tens $ Index.indexName <$> (Index.isContravariant `Prelude.filter` indices tens)
+
+
 -- Add scalar right
 {-# INLINE (.+) #-}
 (.+) :: (
-    Unboxed.Unbox a, Num a
+    Num a, Multilinear Tensor a
     ) => Tensor a 
       -> a 
       -> Tensor a
@@ -596,7 +580,7 @@ -- Subtract scalar right
 {-# INLINE (.-) #-}
 (.-) :: (
-    Unboxed.Unbox a, Num a
+    Num a, Multilinear Tensor a
     ) => Tensor a 
       -> a 
       -> Tensor a
@@ -605,7 +589,7 @@ -- Multiplicate by scalar right
 {-# INLINE (.*) #-}
 (.*) :: (
-    Unboxed.Unbox a, Num a
+    Num a, Multilinear Tensor a
     ) => Tensor a 
       -> a 
       -> Tensor a
@@ -614,7 +598,7 @@ -- Add scalar left
 {-# INLINE (+.) #-}
 (+.) :: (
-    Unboxed.Unbox a, Num a
+    Num a, Multilinear Tensor a
     ) => a 
       -> Tensor a 
       -> Tensor a
@@ -623,7 +607,7 @@ -- Subtract scalar left
 {-# INLINE (-.) #-}
 (-.) :: (
-    Unboxed.Unbox a, Num a
+    Num a, Multilinear Tensor a
     ) => a 
       -> Tensor a 
       -> Tensor a
@@ -632,20 +616,17 @@ -- Multiplicate by scalar left
 {-# INLINE (*.) #-}
 (*.) :: (
-    Unboxed.Unbox a, Num a
+    Num a, Multilinear Tensor a
     ) => a 
       -> Tensor a 
       -> Tensor a
 x *. t = (x*) `Multilinear.Generic.Sequential.map` t
 
-    
-{-| Simple mapping -}
-{-| @map f t@ returns tensor @t2@ in which @t2[i1,i2,...] = f t[i1,i2,...]@ -}
-{-# INLINE map #-}
+-- | Simple mapping
 map :: (
-    Unboxed.Unbox a, Unboxed.Unbox b
-    ) => (a -> b) 
-      -> Tensor a 
+    Multilinear Tensor a, Multilinear Tensor b
+    ) => (a -> b)
+      -> Tensor a
       -> Tensor b
 map f x = case x of
     -- Mapping scalar simply maps its value
@@ -666,7 +647,7 @@     If for some index all elements are removed, the index itself is removed from tensor. -}
 {-# INLINE filter #-}
 filter :: (
-    Unboxed.Unbox a
+    Multilinear Tensor a
     ) => (String -> Int -> Bool) -- ^ filter function
       -> Tensor a                -- ^ tensor to filter
       -> Tensor a
@@ -689,7 +670,7 @@ {-| Filtering one index of tensor. -}
 {-# INLINE filterIndex #-}
 filterIndex :: (
-    Unboxed.Unbox a
+    Multilinear Tensor a
     ) => String        -- ^ Index name to filter
       -> (Int -> Bool) -- ^ filter function
       -> Tensor a      -- ^ tensor to filter
@@ -699,7 +680,7 @@ {-| Zip tensors with binary combinator, assuming they have all indices the same -}
 {-# INLINE zipWith' #-}
 zipWith' :: (
-    Unboxed.Unbox a, Unboxed.Unbox b, Unboxed.Unbox c
+    Multilinear Tensor a, Multilinear Tensor b, Multilinear Tensor c
     ) => (a -> b -> c) 
       -> Tensor a 
       -> Tensor b 
@@ -707,9 +688,9 @@ -- Zipping two Scalars simply combines their values 
 zipWith' f (Scalar x1) (Scalar x2) = Scalar $ f x1 x2
 -- zipping complex tensor with scalar 
-zipWith' f t (Scalar x) = (`f` x) `_map` t
+zipWith' f t (Scalar x) = (`f` x) `Multilinear.Generic.Sequential.map` t
 -- zipping scalar with complex tensor
-zipWith' f (Scalar x) t = (x `f`) `_map` t
+zipWith' f (Scalar x) t = (x `f`) `Multilinear.Generic.Sequential.map` t
 -- Two simple tensors case
 zipWith' f (SimpleFinite index1 v1) (SimpleFinite index2 v2) = 
     if index1 == index2 then 
@@ -725,12 +706,12 @@ 
 {-# INLINE zipWith #-}
 zipWith :: (
-    Unboxed.Unbox a, Unboxed.Unbox b, Unboxed.Unbox c
+    Multilinear Tensor a, Multilinear Tensor b, Multilinear Tensor c
     ) => (a -> b -> c) 
       -> Tensor a 
       -> Tensor b 
       -> Tensor c
 zipWith f t1 t2 = 
-    let t1' = _standardize t1
-        t2' = _standardize t2
+    let t1' = standardize t1
+        t2' = standardize t2
     in  zipWith' f t1' t2'
test/sequential/Test/QuickCheck/Multilinear/Generic/Sequential.hs view
@@ -76,6 +76,6 @@   where ts = pure (*) <*> tensors1D <*> tensors1D
 
 -- | Arbitrary random generating instance of Tensor Double
--- | Simply choose a tensot from tensors list above
+-- | Simply choose a tensor from tensors list above
 instance Arbitrary (Tensor Double) where
     arbitrary = elements tensors3D