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 +14/−0
- massiv.cabal +3/−2
- src/Data/Massiv/Array/Delayed/Pull.hs +11/−38
- src/Data/Massiv/Array/Manifest/Primitive.hs +33/−3
- src/Data/Massiv/Array/Manifest/Storable.hs +53/−24
- src/Data/Massiv/Array/Numeric.hs +650/−43
- src/Data/Massiv/Array/Ops/Fold/Internal.hs +5/−3
- src/Data/Massiv/Core/Exception.hs +9/−0
- src/Data/Massiv/Core/Operations.hs +34/−12
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 (/)