packages feed

massiv 0.5.5.0 → 0.5.6.0

raw patch · 9 files changed

+812/−125 lines, 9 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Data.Massiv.Array.Numeric: (!*!) :: (Load r ix e, Numeric r e) => Array r ix e -> Array r ix e -> Array r ix e
+ Data.Massiv.Array.Numeric: (!+!) :: (Load r ix e, Numeric r e) => Array r ix e -> Array r ix e -> Array r ix e
+ Data.Massiv.Array.Numeric: (!-!) :: (Load r ix e, Numeric r e) => Array r ix e -> Array r ix e -> Array r ix e
+ Data.Massiv.Array.Numeric: (!.!) :: (Numeric r e, Source r Ix1 e) => Vector r e -> Vector r e -> e
+ Data.Massiv.Array.Numeric: (!/!) :: (Load r ix e, NumericFloat r e) => Array r ix e -> Array r ix e -> Array r ix e
+ Data.Massiv.Array.Numeric: (!><!) :: (Numeric r e, Mutable r Ix2 e, Source r' Ix2 e) => Matrix r e -> Matrix r' e -> Matrix D e
+ Data.Massiv.Array.Numeric: (!><) :: (Numeric r e, Source r Ix1 e, Source r Ix2 e) => Matrix r e -> Vector r e -> Vector D e
+ Data.Massiv.Array.Numeric: (.><) :: (MonadThrow m, Numeric r e, Source r Ix1 e, Source r Ix2 e) => Matrix r e -> Vector r e -> m (Vector D e)
+ Data.Massiv.Array.Numeric: (.><.) :: (Numeric r e, Mutable r Ix2 e, Source r' Ix2 e, MonadThrow m) => Matrix r e -> Matrix r' e -> m (Matrix D e)
+ Data.Massiv.Array.Numeric: (/.) :: (Index ix, NumericFloat r e) => e -> Array r ix e -> Array r ix e
+ Data.Massiv.Array.Numeric: (><!) :: (Numeric r e, Mutable r Ix1 e, Mutable r Ix2 e) => Vector r e -> Matrix r e -> Vector D e
+ Data.Massiv.Array.Numeric: (><.) :: (MonadThrow m, Numeric r e, Mutable r Ix1 e, Mutable r Ix2 e) => Vector r e -> Matrix r e -> m (Vector D e)
+ Data.Massiv.Array.Numeric: class Num e => Numeric r e
+ Data.Massiv.Array.Numeric: class (Numeric r e, Floating e) => NumericFloat r e
+ Data.Massiv.Array.Numeric: dotM :: (Numeric r e, Source r Ix1 e, MonadThrow m) => Vector r e -> Vector r e -> m e
+ Data.Massiv.Array.Numeric: multiplyMatrices :: forall r r' e m. (Numeric r e, Mutable r Ix2 e, Source r' Ix2 e, MonadThrow m) => Matrix r e -> Matrix r' e -> m (Matrix D e)
+ Data.Massiv.Array.Numeric: multiplyMatricesTransposed :: (Numeric r e, Manifest r Ix2 e, MonadThrow m) => Matrix r e -> Matrix r e -> m (Matrix D e)
+ Data.Massiv.Array.Numeric: normL2 :: (NumericFloat r e, Source r ix e) => Array r ix e -> e
+ Data.Massiv.Core: throwEither :: Either SomeException a -> a
+ Data.Massiv.Core.Operations: foldArray :: (Numeric r e, Index ix) => (e -> e -> e) -> e -> Array r ix e -> e
+ Data.Massiv.Core.Operations: productArray :: (Numeric r e, Index ix) => Array r ix e -> e
+ Data.Massiv.Core.Operations: scalarDivide :: (NumericFloat r e, Index ix) => e -> Array r ix e -> Array r ix e
+ Data.Massiv.Core.Operations: scalarMinus :: (Numeric r e, Index ix) => e -> Array r ix e -> Array r ix e
+ Data.Massiv.Core.Operations: sumArray :: (Numeric r e, Index ix) => Array r ix e -> e
+ Data.Massiv.Core.Operations: unsafeDotProduct :: (Numeric r e, Index ix) => Array r ix e -> Array r ix e -> e
- Data.Massiv.Array.Numeric: ceilingA :: (Index ix, Numeric r e, RealFrac a, Integral e) => Array r ix a -> Array r ix e
+ Data.Massiv.Array.Numeric: ceilingA :: (Source r ix a, RealFrac a, Integral e) => Array r ix a -> Array D ix e
- Data.Massiv.Array.Numeric: floorA :: (Index ix, Numeric r e, RealFrac a, Integral e) => Array r ix a -> Array r ix e
+ Data.Massiv.Array.Numeric: floorA :: (Source r ix a, RealFrac a, Integral e) => Array r ix a -> Array D ix e
- Data.Massiv.Array.Numeric: infixl 6 -.
+ Data.Massiv.Array.Numeric: infixl 6 !-!
- Data.Massiv.Array.Numeric: infixl 7 ./
+ Data.Massiv.Array.Numeric: infixl 7 !/!
- Data.Massiv.Array.Numeric: roundA :: (Index ix, Numeric r e, RealFrac a, Integral e) => Array r ix a -> Array r ix e
+ Data.Massiv.Array.Numeric: roundA :: (Source r ix a, RealFrac a, Integral e) => Array r ix a -> Array D ix e
- Data.Massiv.Array.Numeric: truncateA :: (Index ix, Numeric r e, RealFrac a, Integral e) => Array r ix a -> Array r ix e
+ Data.Massiv.Array.Numeric: truncateA :: (Source r ix a, RealFrac a, Integral e) => Array r ix a -> Array D ix e
- Data.Massiv.Core.Operations: unsafeLiftArray :: (Numeric r e, Index ix) => (a -> e) -> Array r ix a -> Array r ix e
+ Data.Massiv.Core.Operations: unsafeLiftArray :: (Numeric r e, Index ix) => (e -> e) -> Array r ix e -> Array r ix e
- Data.Massiv.Core.Operations: unsafeLiftArray2 :: (Numeric r e, Index ix) => (a -> b -> e) -> Array r ix a -> Array r ix b -> Array r ix e
+ Data.Massiv.Core.Operations: unsafeLiftArray2 :: (Numeric r e, Index ix) => (e -> e -> e) -> Array r ix e -> Array r ix e -> Array r ix e

Files

CHANGELOG.md view
@@ -1,3 +1,17 @@+# 0.5.6++* Fix `(-.)` (it was incorrectly implemented as a flip of `(.-)`+* Addition of numeric functions:+  * Partial: `!+!`, `!-!`, `!*!`, `!/!`+  * Reciprocal division `/.`+  * More efficient matrix-matrix multiplication: `.><.` and `!><!` (also helpers+    `multiplyMatrices` and `multiplyMatricesTransposed`)+  * More efficient matrix-vector multiplication: `.><` and `!><`+  * New vector-matrix multiplication: `><.` and `><!`+  * Dot product `dotM` and `!.!`+  * Norm `normL2`+* Deprecated `|*|` and `#>`+ # 0.5.5  * Add `takeWhile`, `dropWhile` and `findIndex`
massiv.cabal view
@@ -1,5 +1,5 @@ name:                massiv-version:             0.5.5.0+version:             0.5.6.0 synopsis:            Massiv (Массив) is an Array Library. description:         Multi-dimensional Arrays with fusion, stencils and parallel computation. homepage:            https://github.com/lehins/massiv@@ -18,7 +18,8 @@                     , GHC == 8.6.3                     , GHC == 8.6.4                     , GHC == 8.6.5-                    , GHC == 8.8.1+                    , GHC == 8.8.4+                    , GHC == 8.10.2  flag unsafe-checks   description: Enable all the bounds checks for unsafe functions at the cost of
src/Data/Massiv/Array/Delayed/Pull.hs view
@@ -3,7 +3,6 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-}@@ -219,26 +218,13 @@   instance Num e => Numeric D e where-  -- plusScalar arr e = unsafeLiftArray (+ e) arr-  -- {-# INLINE plusScalar #-}-  -- minusScalar arr e = unsafeLiftArray (subtract e) arr-  -- {-# INLINE minusScalar #-}-  -- multiplyScalar arr e = unsafeLiftArray (* e) arr-  -- {-# INLINE multiplyScalar #-}-  -- absPointwise = unsafeLiftArray abs-  -- {-# INLINE absPointwise #-}-  -- additionPointwise = unsafeLiftArray2 (+)-  -- {-# INLINE additionPointwise #-}-  -- subtractionPointwise = unsafeLiftArray2 (-)-  -- {-# INLINE subtractionPointwise #-}-  -- multiplicationPointwise = unsafeLiftArray2 (*)-  -- {-# INLINE multiplicationPointwise #-}-  -- powerPointwise arr pow = unsafeLiftArray (^ pow) arr-  -- {-# INLINE powerPointwise #-}-  -- powerSumArray arr = sumArray . powerPointwise arr-  -- {-# INLINE powerSumArray #-}-  -- unsafeDotProduct a1 a2 = sumArray (multiplicationPointwise a1 a2)-  -- {-# INLINE unsafeDotProduct #-}+  foldArray f !initAcc arr = go initAcc 0+    where+      !len = totalElem (dSize arr)+      go !acc i+        | i < len = go (f acc (unsafeLinearIndex arr i)) (i + 1)+        | otherwise = acc+  {-# INLINE foldArray #-}   unsafeLiftArray f arr = arr {dIndex = f . dIndex arr}   {-# INLINE unsafeLiftArray #-}   unsafeLiftArray2 f a1 a2 =@@ -247,19 +233,7 @@   {-# INLINE unsafeLiftArray2 #-}  -instance Floating e => NumericFloat D e where-  -- recipPointwise = liftDArray recip-  -- {-# INLINE recipPointwise #-}-  -- sqrtPointwise = liftDArray sqrt-  -- {-# INLINE sqrtPointwise #-}-  -- floorPointwise = liftDArray floor-  -- {-# INLINE floorPointwise #-}-  -- ceilingPointwise = liftDArray ceiling-  -- {-# INLINE ceilingPointwise #-}-  -- divisionPointwise = liftDArray2 (/)-  -- {-# INLINE divisionPointwise #-}-  -- divideScalar arr e = liftDArray (/ e) arr-  -- {-# INLINE divideScalar #-}+instance Floating e => NumericFloat D e   @@ -272,15 +246,14 @@ "delay" [~1] forall (arr :: Array D ix e) . delay arr = arr  #-} --- TODO: switch to zipWith -- | /O(min (n1, n2))/ - Compute array equality by applying a comparing function to each element. eq :: (Source r1 ix e1, Source r2 ix e2) =>       (e1 -> e2 -> Bool) -> Array r1 ix e1 -> Array r2 ix e2 -> Bool eq f arr1 arr2 =   (size arr1 == size arr2) &&-  F.and-    (DArray (getComp arr1 <> getComp arr2) (size arr1) $ \ix ->-       f (unsafeIndex arr1 ix) (unsafeIndex arr2 ix))+  not (A.any not+       (DArray (getComp arr1 <> getComp arr2) (size arr1) $ \ix ->+           f (unsafeIndex arr1 ix) (unsafeIndex arr2 ix))) {-# INLINE eq #-}  -- | /O(min (n1, n2))/ - Compute array ordering by applying a comparing function to each element.
src/Data/Massiv/Array/Manifest/Primitive.hs view
@@ -50,11 +50,12 @@  import Control.DeepSeq (NFData(..), deepseq) import Control.Monad.Primitive (PrimMonad(..), primitive_)-import Data.Massiv.Array.Delayed.Pull (eq, ord)+import Data.Massiv.Array.Delayed.Pull -- (eq, ord) import Data.Massiv.Array.Manifest.Internal import Data.Massiv.Array.Manifest.List as A import Data.Massiv.Array.Mutable import Data.Massiv.Core.Common+import Data.Massiv.Core.Operations import Data.Massiv.Core.List import Data.Massiv.Vector.Stream as S (steps, isteps) import Data.Maybe (fromMaybe)@@ -97,8 +98,8 @@   setComp c arr = arr { pComp = c }   {-# INLINE setComp #-} -  makeArray !comp !sz f = unsafePerformIO $ generateArray comp sz (return . f)-  {-# INLINE makeArray #-}+  makeArrayLinear !comp !sz f = unsafePerformIO $ generateArrayLinear comp sz (return . f)+  {-# INLINE makeArrayLinear #-}  instance (Prim e, Index ix) => Source P ix e where   unsafeLinearIndex _arr@(PArray _ _ o a) i =@@ -244,6 +245,35 @@   {-# INLINE toStream #-}   toStreamIx = S.isteps   {-# INLINE toStreamIx #-}+++instance (Prim e, Num e) => Numeric P e where+  unsafeDotProduct a1 a2 = go 0 0+    where+      !len = totalElem (size a1)+      go !acc i+        | i < len = go (acc + unsafeLinearIndex a1 i * unsafeLinearIndex a2 i) (i + 1)+        | otherwise = acc+  {-# INLINE unsafeDotProduct #-}+  foldArray f !initAcc arr = go initAcc 0+    where+      !len = totalElem (size arr)+      go !acc i+        | i < len = go (f acc (unsafeLinearIndex arr i)) (i + 1)+        | otherwise = acc+  {-# INLINE foldArray #-}+  unsafeLiftArray f arr = makeArrayLinear (getComp arr) (size arr) (f . unsafeLinearIndex arr)+  {-# INLINE unsafeLiftArray #-}+  unsafeLiftArray2 f a1 a2 =+    makeArrayLinear+      (getComp a1 <> getComp a2)+      (SafeSz (liftIndex2 min (unSz (size a1)) (unSz (size a2)))) $ \ !i ->+      f (unsafeLinearIndex a1 i) (unsafeLinearIndex a2 i)+  {-# INLINE unsafeLiftArray2 #-}+++instance (Prim e, Floating e) => NumericFloat P e+  instance ( Prim e          , IsList (Array L ix e)
src/Data/Massiv/Array/Manifest/Storable.hs view
@@ -18,7 +18,7 @@ module Data.Massiv.Array.Manifest.Storable   ( S (..)   , Array(..)-  , VS.Storable+  , Storable   , toStorableVector   , toStorableMVector   , fromStorableVector@@ -45,6 +45,7 @@ import Data.Massiv.Array.Mutable import Data.Massiv.Core.Common import Data.Massiv.Core.List+import Data.Massiv.Core.Operations import qualified Data.Vector.Generic.Mutable as VGM import qualified Data.Vector.Storable as VS import qualified Data.Vector.Storable.Mutable as MVS@@ -67,7 +68,7 @@                                     , sData :: !(VS.Vector e)                                     } -instance (Ragged L ix e, Show e, VS.Storable e) => Show (Array S ix e) where+instance (Ragged L ix e, Show e, Storable e) => Show (Array S ix e) where   showsPrec = showsArrayPrec id   showList = showArrayList @@ -75,15 +76,15 @@   rnf (SArray c sz v) = c `deepseq` sz `deepseq` v `deepseq` ()   {-# INLINE rnf #-} -instance (VS.Storable e, Eq e, Index ix) => Eq (Array S ix e) where+instance (Storable e, Eq e, Index ix) => Eq (Array S ix e) where   (==) = eq (==)   {-# INLINE (==) #-} -instance (VS.Storable e, Ord e, Index ix) => Ord (Array S ix e) where+instance (Storable e, Ord e, Index ix) => Ord (Array S ix e) where   compare = ord compare   {-# INLINE compare #-} -instance (VS.Storable e, Index ix) => Construct S ix e where+instance (Storable e, Index ix) => Construct S ix e where   setComp c arr = arr { sComp = c }   {-# INLINE setComp #-} @@ -91,7 +92,7 @@   {-# INLINE makeArray #-}  -instance (VS.Storable e, Index ix) => Source S ix e where+instance (Storable e, Index ix) => Source S ix e where   unsafeLinearIndex (SArray _ _ v) =     INDEX_CHECK("(Source S ix e).unsafeLinearIndex", Sz . VS.length, VS.unsafeIndex) v   {-# INLINE unsafeLinearIndex #-}@@ -102,13 +103,13 @@   unsafeResize !sz !arr = arr { sSize = sz }   {-# INLINE unsafeResize #-} -instance (VS.Storable e, Index ix) => Extract S ix e where+instance (Storable e, Index ix) => Extract S ix e where   unsafeExtract !sIx !newSz !arr = unsafeExtract sIx newSz (toManifest arr)   {-# INLINE unsafeExtract #-}   -instance ( VS.Storable e+instance ( Storable e          , Index ix          , Index (Lower ix)          , Elt M ix e ~ Array M (Lower ix) e@@ -118,7 +119,7 @@   unsafeOuterSlice arr = unsafeOuterSlice (toManifest arr)   {-# INLINE unsafeOuterSlice #-} -instance ( VS.Storable e+instance ( Storable e          , Index ix          , Index (Lower ix)          , Elt M ix e ~ Array M (Lower ix) e@@ -128,19 +129,19 @@   unsafeInnerSlice arr = unsafeInnerSlice (toManifest arr)   {-# INLINE unsafeInnerSlice #-} -instance {-# OVERLAPPING #-} VS.Storable e => Slice S Ix1 e where+instance {-# OVERLAPPING #-} Storable e => Slice S Ix1 e where   unsafeSlice arr i _ _ = pure (unsafeLinearIndex arr i)   {-# INLINE unsafeSlice #-}  -instance (Index ix, VS.Storable e) => Manifest S ix e where+instance (Index ix, Storable e) => Manifest S ix e where    unsafeLinearIndexM (SArray _ _ v) =     INDEX_CHECK("(Manifest S ix e).unsafeLinearIndexM", Sz . VS.length, VS.unsafeIndex) v   {-# INLINE unsafeLinearIndexM #-}  -instance (Index ix, VS.Storable e) => Mutable S ix e where+instance (Index ix, Storable e) => Mutable S ix e where   data MArray s S ix e = MSArray !(Sz ix) !(VS.MVector s e)    msize (MSArray sz _) = sz@@ -204,7 +205,7 @@   {-# INLINE unsafeLinearGrow #-}  -instance (Index ix, VS.Storable e) => Load S ix e where+instance (Index ix, Storable e) => Load S ix e where   type R S = M   size = sSize   {-# INLINE size #-}@@ -213,16 +214,44 @@   loadArrayM !scheduler !arr = splitLinearlyWith_ scheduler (elemsCount arr) (unsafeLinearIndex arr)   {-# INLINE loadArrayM #-} -instance (Index ix, VS.Storable e) => StrideLoad S ix e+instance (Index ix, Storable e) => StrideLoad S ix e -instance (Index ix, VS.Storable e) => Stream S ix e where+instance (Index ix, Storable e) => Stream S ix e where   toStream = S.steps   {-# INLINE toStream #-}   toStreamIx = S.isteps   {-# INLINE toStreamIx #-}  -instance ( VS.Storable e+instance (Storable e, Num e) => Numeric S e where+  unsafeDotProduct a1 a2 = go 0 0+    where+      !len = totalElem (size a1)+      go !acc i+        | i < len = go (acc + unsafeLinearIndex a1 i * unsafeLinearIndex a2 i) (i + 1)+        | otherwise = acc+  {-# INLINE unsafeDotProduct #-}+  foldArray f !initAcc arr = go initAcc 0+    where+      !len = totalElem (size arr)+      go !acc i+        | i < len = go (f acc (unsafeLinearIndex arr i)) (i + 1)+        | otherwise = acc+  {-# INLINE foldArray #-}+  unsafeLiftArray f arr = makeArrayLinear (getComp arr) (size arr) (f . unsafeLinearIndex arr)+  {-# INLINE unsafeLiftArray #-}+  unsafeLiftArray2 f a1 a2 =+    makeArrayLinear+      (getComp a1 <> getComp a2)+      (SafeSz (liftIndex2 min (unSz (size a1)) (unSz (size a2)))) $ \ !i ->+      f (unsafeLinearIndex a1 i) (unsafeLinearIndex a2 i)+  {-# INLINE unsafeLiftArray2 #-}+++instance (Storable e, Floating e) => NumericFloat S e+++instance ( Storable e          , IsList (Array L ix e)          , Nested LN ix e          , Nested L ix e@@ -239,7 +268,7 @@ -- referential transparency. -- -- @since 0.1.3-unsafeWithPtr :: (MonadUnliftIO m, VS.Storable a) => Array S ix a -> (Ptr a -> m b) -> m b+unsafeWithPtr :: (MonadUnliftIO m, Storable a) => Array S ix a -> (Ptr a -> m b) -> m b unsafeWithPtr arr f = withRunInIO $ \run -> VS.unsafeWith (sData arr) (run . f) {-# INLINE unsafeWithPtr #-} @@ -247,7 +276,7 @@ -- | A pointer to the beginning of the mutable array. -- -- @since 0.1.3-withPtr :: (MonadUnliftIO m, VS.Storable a) => MArray RealWorld S ix a -> (Ptr a -> m b) -> m b+withPtr :: (MonadUnliftIO m, Storable a) => MArray RealWorld S ix a -> (Ptr a -> m b) -> m b withPtr (MSArray _ mv) f = withRunInIO $ \run -> MVS.unsafeWith mv (run . f) {-# INLINE withPtr #-} @@ -285,21 +314,21 @@ -- | /O(1)/ - Yield the underlying `ForeignPtr` together with its length. -- -- @since 0.3.0-unsafeArrayToForeignPtr :: VS.Storable e => Array S ix e -> (ForeignPtr e, Int)+unsafeArrayToForeignPtr :: Storable e => Array S ix e -> (ForeignPtr e, Int) unsafeArrayToForeignPtr = VS.unsafeToForeignPtr0 . toStorableVector {-# INLINE unsafeArrayToForeignPtr #-}  -- | /O(1)/ - Yield the underlying `ForeignPtr` together with its length. -- -- @since 0.3.0-unsafeMArrayToForeignPtr :: VS.Storable e => MArray s S ix e -> (ForeignPtr e, Int)+unsafeMArrayToForeignPtr :: Storable e => MArray s S ix e -> (ForeignPtr e, Int) unsafeMArrayToForeignPtr = MVS.unsafeToForeignPtr0 . toStorableMVector {-# INLINE unsafeMArrayToForeignPtr #-}  -- | /O(1)/ - Wrap a `ForeignPtr` and it's size into a pure storable array. -- -- @since 0.3.0-unsafeArrayFromForeignPtr0 :: VS.Storable e => Comp -> ForeignPtr e -> Sz1 -> Array S Ix1 e+unsafeArrayFromForeignPtr0 :: Storable e => Comp -> ForeignPtr e -> Sz1 -> Array S Ix1 e unsafeArrayFromForeignPtr0 comp ptr sz =   SArray {sComp = comp, sSize = sz, sData = VS.unsafeFromForeignPtr0 ptr (unSz sz)} {-# INLINE unsafeArrayFromForeignPtr0 #-}@@ -307,7 +336,7 @@ -- | /O(1)/ - Wrap a `ForeignPtr`, an offset and it's size into a pure storable array. -- -- @since 0.3.0-unsafeArrayFromForeignPtr :: VS.Storable e => Comp -> ForeignPtr e -> Int -> Sz1 -> Array S Ix1 e+unsafeArrayFromForeignPtr :: Storable e => Comp -> ForeignPtr e -> Int -> Sz1 -> Array S Ix1 e unsafeArrayFromForeignPtr comp ptr offset sz =   SArray {sComp = comp, sSize = sz, sData = VS.unsafeFromForeignPtr ptr offset (unSz sz)} {-# INLINE unsafeArrayFromForeignPtr #-}@@ -317,7 +346,7 @@ -- modify the pointer, unless the array gets frozen prior to modification. -- -- @since 0.3.0-unsafeMArrayFromForeignPtr0 :: VS.Storable e => ForeignPtr e -> Sz1 -> MArray s S Ix1 e+unsafeMArrayFromForeignPtr0 :: Storable e => ForeignPtr e -> Sz1 -> MArray s S Ix1 e unsafeMArrayFromForeignPtr0 fp sz =   MSArray sz (MVS.unsafeFromForeignPtr0 fp (unSz sz)) {-# INLINE unsafeMArrayFromForeignPtr0 #-}@@ -327,7 +356,7 @@ -- still safe to modify the pointer, unless the array gets frozen prior to modification. -- -- @since 0.3.0-unsafeMArrayFromForeignPtr :: VS.Storable e => ForeignPtr e -> Int -> Sz1 -> MArray s S Ix1 e+unsafeMArrayFromForeignPtr :: Storable e => ForeignPtr e -> Int -> Sz1 -> MArray s S Ix1 e unsafeMArrayFromForeignPtr fp offset sz =   MSArray sz (MVS.unsafeFromForeignPtr fp offset (unSz sz)) {-# INLINE unsafeMArrayFromForeignPtr #-}
src/Data/Massiv/Array/Numeric.hs view
@@ -12,20 +12,44 @@ -- Portability : non-portable -- module Data.Massiv.Array.Numeric-  ( -- * Num-    (.+.)+  ( -- * Numeric+    Numeric+  , NumericFloat+    -- ** Pointwise addition   , (.+)   , (+.)-  , (.-.)+  , (.+.)+  , (!+!)+  -- ** Pointwise subtraction   , (.-)   , (-.)-  , (.*.)+  , (.-.)+  , (!-!)+  -- ** Pointwise multiplication   , (.*)   , (*.)+  , (.*.)+  , (!*!)   , (.^)+  -- ** Dot product+  , (!.!)+  , dotM+  -- ** Matrix multiplication+  , (.><)+  , (!><)+  , (><.)+  , (><!)+  , (.><.)+  , (!><!)+  , multiplyMatrices+  , multiplyMatricesTransposed+  -- Deprecated:   , (#>)   , (|*|)   , multiplyTransposed+  -- * Norms+  , normL2+  -- ** Simple matrices   , identityMatrix   , lowerTriangular   , upperTriangular@@ -41,8 +65,10 @@   , quotRemA   , divModA   -- * Fractional-  , (./.)   , (./)+  , (/.)+  , (./.)+  , (!/!)   , (.^^)   , recipA   , fromRationalA@@ -74,6 +100,7 @@   , atan2A   ) where +import Data.Massiv.Array.Manifest import Data.Massiv.Array.Delayed.Pull import Data.Massiv.Array.Delayed.Push import Data.Massiv.Array.Manifest.Internal@@ -85,11 +112,14 @@ import Data.Massiv.Core.Common import Data.Massiv.Core.Operations import Prelude as P-+import System.IO.Unsafe+import Control.Scheduler+import Control.Monad (when)+import qualified Data.Foldable as F  infixr 8  .^, .^^-infixl 7  .*., .*, *., ./., ./, `quotA`, `remA`, `divA`, `modA`-infixl 6  .+., .+, +., .-., .-, -.+infixl 7  !*!, .*., .*, *., !/!, ./., ./, /., `quotA`, `remA`, `divA`, `modA`+infixl 6  !+!, .+., .+, +., !-!, .-., .-, -.  liftArray2Matching   :: (Source r1 ix a, Source r2 ix b)@@ -130,15 +160,35 @@ {-# INLINE liftNumericArray2M #-}  --- | Add two arrays together pointwise. Throws `SizeMismatchException` if arrays sizes do--- not match.+-- | Add two arrays together pointwise. Same as `!+!` but produces monadic computation+-- that allows for handling failure. --+-- /__Throws Exception__/: `SizeMismatchException` when array sizes do not match.+-- -- @since 0.4.0 (.+.) ::      (Load r ix e, Numeric r e, MonadThrow m) => Array r ix e -> Array r ix e -> m (Array r ix e) (.+.) = liftNumericArray2M additionPointwise {-# INLINE (.+.) #-} +-- | Add two arrays together pointwise. Prefer to use monadic version of this function+-- `.+.` whenever possible, because it is better to avoid partial functions.+--+-- [Partial] Mismatched array sizes will result in an impure exception being thrown.+--+-- ====__Example__+--+-- >>> let a1 = Ix1 0 ... 10+-- >>> let a2 = Ix1 20 ... 30+-- >>> a1 !+! a2+-- Array D Seq (Sz1 11)+--   [ 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40 ]+--+-- @since 0.5.6+(!+!) :: (Load r ix e, Numeric r e) => Array r ix e -> Array r ix e -> Array r ix e+(!+!) a1 a2 = throwEither (a1 .+. a2)+{-# INLINE (!+!) #-}+ -- | Add a scalar to each element of the array. Array is on the left. -- -- @since 0.1.0@@ -153,9 +203,11 @@ (+.) = flip plusScalar {-# INLINE (+.) #-} --- | Subtract two arrays pointwise. Throws `SizeMismatchException` if arrays sizes do not--- match.+-- | Subtract two arrays pointwise. Same as `!-!` but produces monadic computation that+-- allows for handling failure. --+-- /__Throws Exception__/: `SizeMismatchException` when array sizes do not match.+-- -- @since 0.4.0 (.-.) ::      (Load r ix e, Numeric r e, MonadThrow m) => Array r ix e -> Array r ix e -> m (Array r ix e)@@ -163,57 +215,123 @@ {-# INLINE (.-.) #-}  +-- | Subtract one array from another pointwise. Prefer to use monadic version of this+-- function `.-.` whenever possible, because it is better to avoid partial functions.+--+-- [Partial] Mismatched array sizes will result in an impure exception being thrown.+--+-- ====__Example__+--+-- >>> let a1 = Ix1 0 ... 10+-- >>> let a2 = Ix1 20 ... 30+-- >>> a1 !-! a2+-- Array D Seq (Sz1 11)+--   [ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20 ]+--+-- @since 0.5.6+(!-!) :: (Load r ix e, Numeric r e) => Array r ix e -> Array r ix e -> Array r ix e+(!-!) a1 a2 = throwEither (a1 .-. a2)+{-# INLINE (!-!) #-}+ -- | Subtract a scalar from each element of the array. Array is on the left. ----- @since 0.1.0+-- @since 0.4.0 (.-) :: (Index ix, Numeric r e) => Array r ix e -> e -> Array r ix e (.-) = minusScalar {-# INLINE (.-) #-} --- | Subtract a scalar from each element of the array. Array is on the right.+-- | Subtract each element of the array from a scalar. Array is on the right. ----- @since 0.4.0+-- @since 0.5.6 (-.) :: (Index ix, Numeric r e) => e -> Array r ix e -> Array r ix e-(-.) = flip minusScalar+(-.) = scalarMinus {-# INLINE (-.) #-}  --- | Multiply two arrays together pointwise.+-- | Multiply two arrays together pointwise. Same as `!*!` but produces monadic+-- computation that allows for handling failure. --+-- /__Throws Exception__/: `SizeMismatchException` when array sizes do not match.+-- -- @since 0.4.0 (.*.) ::      (Load r ix e, Numeric r e, MonadThrow m) => Array r ix e -> Array r ix e -> m (Array r ix e) (.*.) = liftNumericArray2M multiplicationPointwise {-# INLINE (.*.) #-} ++-- | Multiplication of two arrays pointwise. Prefer to use monadic version of this+-- function `.*.` whenever possible, because it is better to avoid partial functions.+--+-- [Partial] Mismatched array sizes will result in an impure exception being thrown.+--+-- ====__Example__+--+-- >>> let a1 = Ix1 0 ... 10+-- >>> let a2 = Ix1 20 ... 30+-- >>> a1 !*! a2+-- Array D Seq (Sz1 11)+--   [ 0, 21, 44, 69, 96, 125, 156, 189, 224, 261, 300 ]+--+-- @since 0.5.6+(!*!) :: (Load r ix e, Numeric r e) => Array r ix e -> Array r ix e -> Array r ix e+(!*!) a1 a2 = throwEither (a1 .*. a2)+{-# INLINE (!*!) #-}+++-- | Multiply each element of the array by a scalar value. Scalar is on the right.+--+-- ====__Example__+--+-- >>> let arr = Ix1 20 ..: 25+-- >>> arr+-- Array D Seq (Sz1 5)+--   [ 20, 21, 22, 23, 24 ]+-- >>> arr .* 10+-- Array D Seq (Sz1 5)+--   [ 200, 210, 220, 230, 240 ]+--+-- @since 0.4.0 (.*) :: (Index ix, Numeric r e) => Array r ix e -> e -> Array r ix e (.*) = multiplyScalar {-# INLINE (.*) #-} ++-- | Multiply each element of the array by a scalar value. Scalar is on the left.+--+-- ====__Example__+--+-- >>> let arr = Ix1 20 ..: 25+-- >>> arr+-- Array D Seq (Sz1 5)+--   [ 20, 21, 22, 23, 24 ]+-- >>> 10 *. arr+-- Array D Seq (Sz1 5)+--   [ 200, 210, 220, 230, 240 ]+--+-- @since 0.4.0 (*.) :: (Index ix, Numeric r e) => e -> Array r ix e -> Array r ix e (*.) = flip multiplyScalar {-# INLINE (*.) #-} ++-- | Raise each element of the array to a power.+--+-- ====__Example__+--+-- >>> let arr = Ix1 20 ..: 25+-- >>> arr+-- Array D Seq (Sz1 5)+--   [ 20, 21, 22, 23, 24 ]+-- >>> arr .^ 3+-- Array D Seq (Sz1 5)+--   [ 8000, 9261, 10648, 12167, 13824 ]+--+-- @since 0.4.0 (.^) :: (Index ix, Numeric r e) => Array r ix e -> Int -> Array r ix e (.^) = powerPointwise {-# INLINE (.^) #-} --- | Matrix multiplication------ Inner dimensions must agree, otherwise `SizeMismatchException`.-(|*|) ::-     (Mutable r Ix2 e, Source r' Ix2 e, OuterSlice r Ix2 e, Source (R r) Ix1 e, Num e, MonadThrow m)-  => Array r Ix2 e-  -> Array r' Ix2 e-  -> m (Array r Ix2 e)-(|*|) a1 a2 = compute <$> multArrs a1 a2-{-# INLINE [1] (|*|) #-}--{-# RULES-"multDoubleTranspose" [~1] forall arr1 arr2 . arr1 |*| transpose arr2 =-    multiplyTransposedFused arr1 (convert arr2)- #-}- -- | Matrix-vector product -- -- Inner dimensions must agree, otherwise `SizeMismatchException`@@ -231,9 +349,244 @@     Sz2 mRows mCols = size mm     Sz1 n = size v {-# INLINE (#>) #-}+{-# DEPRECATED (#>) "In favor of (`.><`)" #-}  +-- | Dot product of two vectors.+--+-- [Partial] Throws an impure exception when lengths of vectors do not match+--+-- @since 0.5.6+(!.!) :: (Numeric r e, Source r Ix1 e) => Vector r e -> Vector r e -> e+(!.!) v1 v2 = throwEither $ dotM v1 v2+{-# INLINE (!.!) #-} +-- | Dot product of two vectors.+--+-- /__Throws Exception__/: `SizeMismatchException` when lengths of vectors do not match+--+-- @since 0.5.6+dotM :: (Numeric r e, Source r Ix1 e, MonadThrow m) => Vector r e -> Vector r e -> m e+dotM v1 v2+  | size v1 /= size v2 = throwM $ SizeMismatchException (size v1) (size v2)+  | comp == Seq = pure $! unsafeDotProduct v1 v2+  | otherwise = pure $! unsafePerformIO $ unsafeDotProductIO v1 v2+  where+    comp = getComp v1 <> getComp v2+{-# INLINE dotM #-}++-- | Compute L2 norm of an array.+--+-- @since 0.5.6+normL2 :: (NumericFloat r e, Source r ix e) => Array r ix e -> e+normL2 v+  | getComp v == Seq = sqrt $! unsafeDotProduct v v+  | otherwise = sqrt $! unsafePerformIO $ unsafeDotProductIO v v+{-# INLINE normL2 #-}++unsafeDotProductIO ::+     (MonadUnliftIO m, Numeric r b, Source r ix b)+  => Array r ix b+  -> Array r ix b+  -> m b+unsafeDotProductIO v1 v2 = do+  results <-+    withScheduler comp $ \scheduler ->+      splitLinearly (numWorkers scheduler) totalLength $ \chunkLength slackStart -> do+        let n = SafeSz chunkLength+        loopM_ 0 (< slackStart) (+ chunkLength) $ \ !start ->+          scheduleWork scheduler $+          pure $! unsafeDotProduct (unsafeLinearSlice start n v1) (unsafeLinearSlice start n v2)+        when (slackStart < totalLength) $ do+          let k = SafeSz (totalLength - slackStart)+          scheduleWork scheduler $+            pure $!+            unsafeDotProduct (unsafeLinearSlice slackStart k v1) (unsafeLinearSlice slackStart k v2)+  pure $! F.foldl' (+) 0 results+  where+    totalLength = totalElem (size v1)+    comp = getComp v1 <> getComp v2+{-# INLINE unsafeDotProductIO #-}+++-- | Multiply a matrix by a column vector. Same as `!><` but produces monadic+-- computation that allows for handling failure.+--+-- /__Throws Exception__/: `SizeMismatchException` when inner dimensions of arrays do not match.+--+-- @since 0.5.6+(.><) :: (MonadThrow m, Numeric r e, Source r Ix1 e, Source r Ix2 e) =>+         Matrix r e -- ^ Matrix+      -> Vector r e -- ^ Column vector (Used many times, so make sure it is computed)+      -> m (Vector D e)+(.><) mm v+  | mCols /= n = throwM $ SizeMismatchException (size mm) (Sz2 n 1)+  | otherwise = pure $ makeArray (getComp mm <> getComp v) (Sz1 mRows) $ \i ->+      unsafeDotProduct (unsafeLinearSlice (i * n) sz mm) v+  where+    Sz2 mRows mCols = size mm+    sz@(Sz1 n) = size v+{-# INLINE (.><) #-}+++-- | Multiply a matrix by a column vector+--+-- [Partial] Throws impure exception when inner dimensions do not agree+--+-- @since 0.5.6+(!><) ::+     (Numeric r e, Source r Ix1 e, Source r Ix2 e)+  => Matrix r e -- ^ Matrix+  -> Vector r e -- ^ Column vector (Used many times, so make sure it is computed)+  -> Vector D e+(!><) mm v = throwEither (mm .>< v)+{-# INLINE (!><) #-}+++-- | Multiply a row vector by a matrix. Same as `><!` but produces monadic computation+-- that allows for handling failure.+--+-- /__Throws Exception__/: `SizeMismatchException` when inner dimensions of arrays do not match.+--+-- @since 0.5.6+(><.) :: (MonadThrow m, Numeric r e, Mutable r Ix1 e, Mutable r Ix2 e) =>+         Vector r e -- ^ Row vector+      -> Matrix r e -- ^ Matrix+      -> m (Vector D e)+(><.) v mm+  | mRows /= n = throwM $ SizeMismatchException (Sz2 1 n) (size mm)+  | otherwise = pure $ makeArray (getComp mm <> getComp v) (Sz1 mCols) $ \i ->+      unsafeDotProduct (unsafeLinearSlice (i * n) sz mm') v+  where+    Sz2 mRows mCols = size mm+    mm' = compute (transpose mm)+    sz@(Sz1 n) = size v+{-# INLINE (><.) #-}+++-- | Multiply a row vector by a matrix.+--+-- [Partial] Throws impure exception when inner dimensions do not agree+--+-- @since 0.5.6+(><!) ::+     (Numeric r e, Mutable r Ix1 e, Mutable r Ix2 e)+  => Vector r e -- ^ Row vector+  -> Matrix r e -- ^ Matrix+  -> Vector D e+(><!) v mm = throwEither (v ><. mm)+{-# INLINE (><!) #-}++++-- | Multiply two matrices together.+--+-- [Partial] Inner dimension must agree+--+-- ====__Examples__+--+-- >>> a1 = makeArrayR P Seq (Sz2 5 6) $ \(i :. j) -> i + j+-- >>> a2 = makeArrayR D Seq (Sz2 6 5) $ \(i :. j) -> i - j+-- >>> a1 !><! a2+-- Array D Seq (Sz (5 :. 5))+--   [ [ 55, 40, 25, 10, -5 ]+--   , [ 70, 49, 28, 7, -14 ]+--   , [ 85, 58, 31, 4, -23 ]+--   , [ 100, 67, 34, 1, -32 ]+--   , [ 115, 76, 37, -2, -41 ]+--   ]+--+-- @since 0.5.6+(!><!) :: (Numeric r e, Mutable r Ix2 e, Source r' Ix2 e) => Matrix r e -> Matrix r' e -> Matrix D e+(!><!) a1 a2 = throwEither (a1 `multiplyMatrices` a2)+{-# INLINE (!><!) #-}++-- | Matrix multiplication. Same as `!><!` but produces monadic computation that allows+-- for handling failure.+--+-- /__Throws Exception__/: `SizeMismatchException` when inner dimensions of arrays do not match.+--+-- @since 0.5.6+(.><.) ::+     (Numeric r e, Mutable r Ix2 e, Source r' Ix2 e, MonadThrow m)+  => Matrix r e+  -> Matrix r' e+  -> m (Matrix D e)+(.><.) = multiplyMatrices+{-# INLINE (.><.) #-}+++-- | Synonym for `.><.`+--+-- @since 0.5.6+multiplyMatrices ::+     forall r r' e m. (Numeric r e, Mutable r Ix2 e, Source r' Ix2 e, MonadThrow m)+  => Matrix r e+  -> Matrix r' e+  -> m (Matrix D e)+multiplyMatrices arr1 arr2 = multiplyMatricesTransposed arr1 arr2'+  where+    arr2' :: Array r Ix2 e+    arr2' = compute $ transpose arr2+{-# INLINE [1] multiplyMatrices #-}++{-# RULES+"multiplyMatricesTransposed" [~1] forall arr1 arr2 . multiplyMatrices arr1 (transpose arr2) =+    multiplyMatricesTransposedFused arr1 (convert arr2)+ #-}++-- | Computes the matrix-matrix multiplication where second matrix is transposed (i.e. M+-- x N')+--+-- > m1 .><. transpose m2 == multiplyMatricesTransposed m1 m2+--+-- @since 0.5.6+multiplyMatricesTransposed ::+     (Numeric r e, Manifest r Ix2 e, MonadThrow m)+  => Matrix r e+  -> Matrix r  e+  -> m (Matrix D e)+multiplyMatricesTransposed arr1 arr2+  | n1 /= m2 = throwM $ SizeMismatchException (size arr1) (Sz2 m2 n2)+  | otherwise =+    pure $+    DArray (getComp arr1 <> getComp arr2) (SafeSz (m1 :. n2)) $ \(i :. j) ->+      unsafeDotProduct (unsafeLinearSlice (i * n1) n arr1) (unsafeLinearSlice (j * n1) n arr2)+  where+    n = SafeSz n1+    SafeSz (m1 :. n1) = size arr1+    SafeSz (n2 :. m2) = size arr2+{-# INLINE multiplyMatricesTransposed #-}++multiplyMatricesTransposedFused ::+     (Manifest r Ix2 e, Numeric r e, MonadThrow m) => Matrix r e -> Matrix r e -> m (Matrix D e)+multiplyMatricesTransposedFused arr1 arr2 = multiplyMatricesTransposed arr1 arr2+{-# INLINE multiplyMatricesTransposedFused #-}++++--- Below is outdated++-- | Matrix multiplication+--+-- /__Throws Exception__/: `SizeMismatchException` when inner dimensions of arrays do not match.+--+-- @since 0.4.0+(|*|) ::+     (Mutable r Ix2 e, Source r' Ix2 e, OuterSlice r Ix2 e, Source (R r) Ix1 e, Num e, MonadThrow m)+  => Array r Ix2 e+  -> Array r' Ix2 e+  -> m (Array r Ix2 e)+(|*|) a1 a2 = compute <$> multArrs a1 a2+{-# INLINE [1] (|*|) #-}+{-# DEPRECATED (|*|) "In favor of `.><.`" #-}++{-# RULES+"multDoubleTranspose" [~1] forall arr1 arr2 . arr1 |*| transpose arr2 =+    multiplyTransposedFused arr1 (convert arr2)+ #-}++ multiplyTransposedFused ::      ( Mutable r Ix2 e      , OuterSlice r Ix2 e@@ -357,23 +710,39 @@              in wr (toLinearIndex sz ix) (f ix) {-# INLINE upperTriangular #-} -+-- | Negate each element of the array+--+-- @since 0.4.0 negateA :: (Index ix, Numeric r e) => Array r ix e -> Array r ix e negateA = unsafeLiftArray negate {-# INLINE negateA #-} +-- | Apply `abs` to each element of the array+--+-- @since 0.4.0 absA :: (Index ix, Numeric r e) => Array r ix e -> Array r ix e absA = absPointwise {-# INLINE absA #-} +-- | Apply `signum` to each element of the array+--+-- @since 0.4.0 signumA :: (Index ix, Numeric r e) => Array r ix e -> Array r ix e signumA = unsafeLiftArray signum {-# INLINE signumA #-} +-- | Create a singleton array from an `Integer` fromIntegerA :: (Index ix, Num e) => Integer -> Array D ix e fromIntegerA = singleton . fromInteger {-# INLINE fromIntegerA #-}+{-# DEPRECATED fromIntegerA "This almost never a desired behavior. Use `Data.Massiv.Array.Ops.Construct.replicate` instead" #-} +-- | Divide each element of one array by another pointwise. Same as `!/!` but produces+-- monadic computation that allows for handling failure.+--+-- /__Throws Exception__/: `SizeMismatchException` when array sizes do not match.+--+-- @since 0.4.0 (./.) ::      (Load r ix e, NumericFloat r e, MonadThrow m)   => Array r ix e@@ -382,6 +751,57 @@ (./.) = liftNumericArray2M divisionPointwise {-# INLINE (./.) #-} ++-- | Divide two arrays pointwise. Prefer to use monadic version of this function `./.`+-- whenever possible, because it is better to avoid partial functions.+--+-- [Partial] Mismatched array sizes will result in an impure exception being thrown.+--+-- ====__Example__+--+-- >>> let arr1 = fromIntegral <$> (Ix1 20 ..: 25) :: Array D Ix1 Float+-- >>> let arr2 = fromIntegral <$> (Ix1 100 ..: 105) :: Array D Ix1 Float+-- >>> arr1 !/! arr2+-- Array D Seq (Sz1 5)+--   [ 0.2, 0.20792079, 0.21568628, 0.22330096, 0.23076923 ]+--+-- @since 0.5.6+(!/!) :: (Load r ix e, NumericFloat r e) => Array r ix e -> Array r ix e -> Array r ix e+(!/!) a1 a2 = throwEither (a1 ./. a2)+{-# INLINE (!/!) #-}++-- | Divide a scalar value by each element of the array.+--+-- > e /. arr == e *. recipA arr+--+-- ====__Example__+--+-- >>> let arr = fromIntegral <$> (Ix1 20 ..: 25) :: Array D Ix1 Float+-- >>> arr+-- Array D Seq (Sz1 5)+--   [ 20.0, 21.0, 22.0, 23.0, 24.0 ]+-- >>> 100 /. arr+-- Array D Seq (Sz1 5)+--   [ 5.0, 4.7619047, 4.5454545, 4.347826, 4.1666665 ]+--+-- @since 0.5.6+(/.) ::(Index ix,  NumericFloat r e) => e -> Array r ix e -> Array r ix e+(/.) = scalarDivide+{-# INLINE (/.) #-}++-- | Divide each element of the array by a scalar value.+--+-- ====__Example__+--+-- >>> let arr = fromIntegral <$> (Ix1 20 ..: 25) :: Array D Ix1 Float+-- >>> arr+-- Array D Seq (Sz1 5)+--   [ 20.0, 21.0, 22.0, 23.0, 24.0 ]+-- >>> arr ./ 100+-- Array D Seq (Sz1 5)+--   [ 0.2, 0.21, 0.22, 0.23, 0.24 ]+--+-- @since 0.4.0 (./) ::(Index ix,  NumericFloat r e) => Array r ix e -> e -> Array r ix e (./) = divideScalar {-# INLINE (./) #-}@@ -392,6 +812,11 @@ (.^^) arr n = unsafeLiftArray (^^ n) arr {-# INLINE (.^^) #-} +-- | Apply reciprocal to each element of the array.+--+-- > recipA arr == 1 /. arr+--+-- @since 0.4.0 recipA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e recipA = recipPointwise {-# INLINE recipA #-}@@ -402,88 +827,201 @@   => Rational -> Array D ix e fromRationalA = singleton . fromRational {-# INLINE fromRationalA #-}+{-# DEPRECATED fromRationalA "This almost never a desired behavior. Use `Data.Massiv.Array.Ops.Construct.replicate` instead" #-}  piA   :: (Index ix, Floating e)   => Array D ix e piA = singleton pi {-# INLINE piA #-}+{-# DEPRECATED piA "This almost never a desired behavior. Use `Data.Massiv.Array.Ops.Construct.replicate` instead" #-} ++-- | Apply exponent to each element of the array.+--+-- > expA arr == map exp arr+--+-- @since 0.4.0 expA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e expA = unsafeLiftArray exp {-# INLINE expA #-} +-- | Apply square root to each element of the array.+--+-- > sqrtA arr == map sqrt arr+--+-- @since 0.4.0 sqrtA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e sqrtA = unsafeLiftArray sqrt {-# INLINE sqrtA #-} +-- | Apply logarithm to each element of the array.+--+-- > logA arr == map log arr+--+-- @since 0.4.0 logA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e logA = unsafeLiftArray log {-# INLINE logA #-} ++-- | Apply logarithm to each element of the array where the base is in the same cell in+-- the second array.+--+-- > logBaseA arr1 arr2 == zipWith logBase arr1 arr2+--+-- [Partial] Throws an error when arrays do not have matching sizes+--+-- @since 0.4.0 logBaseA   :: (Source r1 ix e, Source r2 ix e, Floating e)   => Array r1 ix e -> Array r2 ix e -> Array D ix e logBaseA = liftArray2Matching logBase {-# INLINE logBaseA #-}+-- TODO: siwtch to+-- (breaking) logBaseA :: Array r ix e -> e -> Array D ix e+-- logBasesM :: Array r ix e -> Array r ix e -> m (Array D ix e) ++++-- | Apply power to each element of the array where the power value is in the same cell+-- in the second array.+--+-- > arr1 .** arr2 == zipWith (**) arr1 arr2+--+-- [Partial] Throws an error when arrays do not have matching sizes+--+-- @since 0.4.0 (.**)   :: (Source r1 ix e, Source r2 ix e, Floating e)   => Array r1 ix e -> Array r2 ix e -> Array D ix e (.**) = liftArray2Matching (**) {-# INLINE (.**) #-}+-- TODO:+-- !**! :: Array r1 ix e -> Array r2 ix e -> Array D ix e+-- .**. :: Array r1 ix e -> Array r2 ix e -> m (Array D ix e)+-- (breaking) .** :: Array r1 ix e -> e -> Array D ix e   +-- | Apply sine function to each element of the array.+--+-- > sinA arr == map sin arr+--+-- @since 0.4.0 sinA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e sinA = unsafeLiftArray sin {-# INLINE sinA #-} +-- | Apply cosine function to each element of the array.+--+-- > cosA arr == map cos arr+--+-- @since 0.4.0 cosA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e cosA = unsafeLiftArray cos {-# INLINE cosA #-} +-- | Apply tangent function to each element of the array.+--+-- > tanA arr == map tan arr+--+-- @since 0.4.0 tanA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e tanA = unsafeLiftArray tan {-# INLINE tanA #-} +-- | Apply arcsine function to each element of the array.+--+-- > asinA arr == map asin arr+--+-- @since 0.4.0 asinA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e asinA = unsafeLiftArray asin {-# INLINE asinA #-} +-- | Apply arctangent function to each element of the array.+--+-- > atanA arr == map atan arr+--+-- @since 0.4.0 atanA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e atanA = unsafeLiftArray atan {-# INLINE atanA #-} +-- | Apply arccosine function to each element of the array.+--+-- > acosA arr == map acos arr+--+-- @since 0.4.0 acosA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e acosA = unsafeLiftArray acos {-# INLINE acosA #-} +-- | Apply hyperbolic sine function to each element of the array.+--+-- > sinhA arr == map sinh arr+--+-- @since 0.4.0 sinhA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e sinhA = unsafeLiftArray sinh {-# INLINE sinhA #-} +-- | Apply hyperbolic tangent function to each element of the array.+--+-- > tanhA arr == map tanh arr+--+-- @since 0.4.0 tanhA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e tanhA = unsafeLiftArray tanh {-# INLINE tanhA #-} +-- | Apply hyperbolic cosine function to each element of the array.+--+-- > coshA arr == map cosh arr+--+-- @since 0.4.0 coshA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e coshA = unsafeLiftArray cosh {-# INLINE coshA #-} +-- | Apply inverse hyperbolic sine function to each element of the array.+--+-- > asinhA arr == map asinh arr+--+-- @since 0.4.0 asinhA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e asinhA = unsafeLiftArray asinh {-# INLINE asinhA #-} +-- | Apply inverse hyperbolic cosine function to each element of the array.+--+-- > acoshA arr == map acosh arr+--+-- @since 0.4.0 acoshA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e acoshA = unsafeLiftArray acosh {-# INLINE acoshA #-} +-- | Apply inverse hyperbolic tangent function to each element of the array.+--+-- > atanhA arr == map atanh arr+--+-- @since 0.4.0 atanhA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e atanhA = unsafeLiftArray atanh {-# INLINE atanhA #-}  +-- | Perform a pointwise quotient where first array contains numerators and the second+-- one denominators+--+-- > quotA arr1 arr2 == zipWith quot arr1 arr2+--+-- [Partial] Mismatched array sizes will result in an impure exception being thrown.+--+-- @since 0.1.0 quotA   :: (Source r1 ix e, Source r2 ix e, Integral e)   => Array r1 ix e -> Array r2 ix e -> Array D ix e@@ -491,18 +1029,44 @@ {-# INLINE quotA #-}  +-- | Perform a pointwise remainder computation+--+-- > remA arr1 arr2 == zipWith rem arr1 arr2+--+-- [Partial] Mismatched array sizes will result in an impure exception being thrown.+--+-- @since 0.1.0 remA   :: (Source r1 ix e, Source r2 ix e, Integral e)   => Array r1 ix e -> Array r2 ix e -> Array D ix e remA = liftArray2Matching rem {-# INLINE remA #-} +-- | Perform a pointwise integer division where first array contains numerators and the+-- second one denominators+--+-- > divA arr1 arr2 == zipWith div arr1 arr2+--+-- [Partial] Mismatched array sizes will result in an impure exception being thrown.+--+-- @since 0.1.0 divA   :: (Source r1 ix e, Source r2 ix e, Integral e)   => Array r1 ix e -> Array r2 ix e -> Array D ix e divA = liftArray2Matching div {-# INLINE divA #-}+-- TODO:+--  * Array r ix e -> Array r ix e -> m (Array r ix e)+--  * Array r ix e -> e -> Array r ix e+--  * e -> Array r ix e -> Array r ix e +-- | Perform a pointwise modulo computation+--+-- > modA arr1 arr2 == zipWith mod arr1 arr2+--+-- [Partial] Mismatched array sizes will result in an impure exception being thrown.+--+-- @since 0.1.0 modA   :: (Source r1 ix e, Source r2 ix e, Integral e)   => Array r1 ix e -> Array r2 ix e -> Array D ix e@@ -511,6 +1075,14 @@   +-- | Perform a pointwise quotient with remainder where first array contains numerators+-- and the second one denominators+--+-- > quotRemA arr1 arr2 == zipWith quotRem arr1 arr2+--+-- [Partial] Mismatched array sizes will result in an impure exception being thrown.+--+-- @since 0.1.0 quotRemA   :: (Source r1 ix e, Source r2 ix e, Integral e)   => Array r1 ix e -> Array r2 ix e -> (Array D ix e, Array D ix e)@@ -518,6 +1090,14 @@ {-# INLINE quotRemA #-}  +-- | Perform a pointwise integer division with modulo where first array contains+-- numerators and the second one denominators+--+-- > divModA arr1 arr2 == zipWith divMod arr1 arr2+--+-- [Partial] Mismatched array sizes will result in an impure exception being thrown.+--+-- @since 0.1.0 divModA   :: (Source r1 ix e, Source r2 ix e, Integral e)   => Array r1 ix e -> Array r2 ix e -> (Array D ix e, Array D ix e)@@ -526,27 +1106,54 @@   +-- | Truncate each element of the array.+--+-- > truncateA arr == map truncate arr+--+-- @since 0.1.0 truncateA-  :: (Index ix, Numeric r e, RealFrac a, Integral e)-  => Array r ix a -> Array r ix e-truncateA = unsafeLiftArray truncate+  :: (Source r ix a, RealFrac a, Integral e)+  => Array r ix a -> Array D ix e+truncateA = A.map truncate {-# INLINE truncateA #-}  -roundA :: (Index ix, Numeric r e, RealFrac a, Integral e) => Array r ix a -> Array r ix e-roundA = unsafeLiftArray round+-- | Round each element of the array.+--+-- > truncateA arr == map truncate arr+--+-- @since 0.1.0+roundA :: (Source r ix a, RealFrac a, Integral e) => Array r ix a -> Array D ix e+roundA = A.map round {-# INLINE roundA #-}  -ceilingA :: (Index ix, Numeric r e, RealFrac a, Integral e) => Array r ix a -> Array r ix e-ceilingA = unsafeLiftArray ceiling+-- | Ceiling of each element of the array.+--+-- > truncateA arr == map truncate arr+--+-- @since 0.1.0+ceilingA :: (Source r ix a, RealFrac a, Integral e) => Array r ix a -> Array D ix e+ceilingA = A.map ceiling {-# INLINE ceilingA #-}  -floorA :: (Index ix, Numeric r e, RealFrac a, Integral e) => Array r ix a -> Array r ix e-floorA = unsafeLiftArray floor+-- | Floor each element of the array.+--+-- > truncateA arr == map truncate arr+--+-- @since 0.1.0+floorA :: (Source r ix a, RealFrac a, Integral e) => Array r ix a -> Array D ix e+floorA = A.map floor {-# INLINE floorA #-} +-- | Perform atan2 pointwise+--+-- > atan2A arr1 arr2 == zipWith atan2 arr1 arr2+--+-- /__Throws Exception__/: `SizeMismatchException` when array sizes do not match.+--+-- @since 0.1.0 atan2A ::      (Load r ix e, Numeric r e, RealFloat e, MonadThrow m)   => Array r ix e
src/Data/Massiv/Array/Ops/Fold/Internal.hs view
@@ -153,10 +153,12 @@ -- -- @since 0.1.0 lazyFoldlS :: Source r ix e => (a -> e -> a) -> a -> Array r ix e -> a-lazyFoldlS f initAcc arr = go initAcc 0 where+lazyFoldlS f initAcc arr = go initAcc 0+  where     len = totalElem (size arr)-    go acc k | k < len = go (f acc (unsafeLinearIndex arr k)) (k + 1)-             | otherwise = acc+    go acc k+      | k < len = go (f acc (unsafeLinearIndex arr k)) (k + 1)+      | otherwise = acc {-# INLINE lazyFoldlS #-}  
src/Data/Massiv/Core/Exception.hs view
@@ -1,9 +1,11 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE GADTs #-}+{-# LANGUAGE LambdaCase #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module Data.Massiv.Core.Exception   ( ImpossibleException(..)   , throwImpossible+  , throwEither   , Uninitialized(..)   , guardNumberOfElements   , Exception(..)@@ -32,6 +34,13 @@ throwImpossible :: Exception e => e -> a throwImpossible = throw . ImpossibleException . toException {-# NOINLINE throwImpossible #-}++throwEither :: Either SomeException a -> a+throwEither =+  \case+    Left exc -> throw exc+    Right res -> res+{-# INLINE throwEither #-}  instance Exception ImpossibleException where   displayException (ImpossibleException exc) =
src/Data/Massiv/Core/Operations.hs view
@@ -21,23 +21,33 @@  class Num e => Numeric r e where -  {-# MINIMAL unsafeLiftArray, unsafeLiftArray2 #-}+  {-# MINIMAL foldArray, unsafeLiftArray, unsafeLiftArray2 #-} -  -- sumArray :: Array r Ix1 e -> e-  -- default sumArray :: Source r Ix1 e => Array r Ix1 e -> e-  -- sumArray = foldlS (+) 0-  -- {-# INLINE sumArray #-}+  -- | Compute sum of all elements in the array+  --+  -- @since 0.5.6+  sumArray :: Index ix => Array r ix e -> e+  sumArray = foldArray (+) 0+  {-# INLINE sumArray #-} -  -- productArray :: Array r Ix1 e -> e-  -- default productArray :: Source r Ix1 e => Array r Ix1 e -> e-  -- productArray = foldlS (*) 1-  -- {-# INLINE productArray #-}+  -- | Compute product of all elements in the array+  --+  -- @since 0.5.6+  productArray :: Index ix => Array r ix e -> e+  productArray = foldArray (*) 1+  {-# INLINE productArray #-}    -- -- | Raise each element in the array to some non-negative power and sum the results   -- powerSumArray :: Array r Ix1 e -> Int -> e -  -- unsafeDotProduct :: Array r Ix1 e -> Array r Ix1 e -> e+  -- | Compute dot product without any extraneous checks+  --+  -- @since 0.5.6+  unsafeDotProduct :: Index ix => Array r ix e -> Array r ix e -> e+  unsafeDotProduct v1 v2 = sumArray $ unsafeLiftArray2 (*) v1 v2+  {-# INLINE unsafeDotProduct #-} +   plusScalar :: Index ix => Array r ix e -> e -> Array r ix e   plusScalar arr e = unsafeLiftArray (+ e) arr   {-# INLINE plusScalar #-}@@ -46,6 +56,10 @@   minusScalar arr e = unsafeLiftArray (subtract e) arr   {-# INLINE minusScalar #-} +  scalarMinus :: Index ix => e -> Array r ix e -> Array r ix e+  scalarMinus e arr = unsafeLiftArray (e -) arr+  {-# INLINE scalarMinus #-}+   multiplyScalar :: Index ix => Array r ix e -> e -> Array r ix e   multiplyScalar arr e = unsafeLiftArray (* e) arr   {-# INLINE multiplyScalar #-}@@ -71,10 +85,14 @@   powerPointwise arr pow = unsafeLiftArray (^ pow) arr   {-# INLINE powerPointwise #-} +  -- | Fold over an array+  --+  -- @since 0.5.6+  foldArray :: Index ix => (e -> e -> e) -> e -> Array r ix e -> e -  unsafeLiftArray :: Index ix => (a -> e) -> Array r ix a -> Array r ix e+  unsafeLiftArray :: Index ix => (e -> e) -> Array r ix e -> Array r ix e -  unsafeLiftArray2 :: Index ix => (a -> b -> e) -> Array r ix a -> Array r ix b -> Array r ix e+  unsafeLiftArray2 :: Index ix => (e -> e -> e) -> Array r ix e -> Array r ix e -> Array r ix e   @@ -83,6 +101,10 @@   divideScalar :: Index ix => Array r ix e -> e -> Array r ix e   divideScalar arr e = unsafeLiftArray (/ e) arr   {-# INLINE divideScalar #-}++  scalarDivide :: Index ix => e -> Array r ix e -> Array r ix e+  scalarDivide e arr = unsafeLiftArray (e /) arr+  {-# INLINE scalarDivide #-}    divisionPointwise :: Index ix => Array r ix e -> Array r ix e -> Array r ix e   divisionPointwise = unsafeLiftArray2 (/)