repa-array-4.2.2.1: Data/Repa/Array/Generic.hs
-- | Generic array API.
--
-- A Repa array is a wrapper around an underlying container structure that
-- holds the array elements.
--
-- In the type (`Array` @l@ @a@), the @l@ specifies the `Layout` of data,
-- which includes the type of the underlying container, as well as how
-- the elements should be arranged in that container. The @a@ specifies
-- the element type.
--
-- The operators provided by this module do not depend on any particular
-- array representation.
--
module Data.Repa.Array.Generic
( Name
-- * Array Access
, Bulk (..), BulkI
, (!)
, length
, first, last
-- * Array Computation
, Load
, Target, TargetI
, computeS, computeIntoS
-- * Operators
-- ** Construction
, empty
, singleton
, generateMaybeS, mapMaybeS
, generateEitherS, mapEitherS
-- ** Conversion
, fromList, fromListInto
, toList
, convert, copy
-- ** Replicating
, replicates
-- ** Mapping
, mapS, map2S
-- ** Merging
, merge
, mergeMaybe
-- ** Splitting
, compact
, compactIn
-- ** Processing
, process
-- ** Unfolding
, unfolds
, StepUnfold (..)
-- ** Filtering
, filter
-- ** Inserting
, insert
-- ** Searching
, findIndex
-- ** Sloshing
-- | Sloshing operators copy array elements into a different arrangement,
-- but do not create new element values.
, concat
, concatWith, unlines
, intercalate
, ConcatDict
-- ** Grouping
, groups
, groupsWith
, GroupsDict
-- ** Folding
-- *** Complete fold
, foldl, sum, product, mean, std
, correlate
-- *** Segmented fold
, folds
, foldsWith
, Folds(..)
, FoldsDict)
where
import Data.Repa.Array.Generic.Load as A
import Data.Repa.Array.Generic.Index as A
import Data.Repa.Array.Meta as A
import Data.Repa.Array.Internals.Bulk as A
import Data.Repa.Array.Internals.Target as A
import Data.Repa.Array.Internals.Operator.Concat as A
import Data.Repa.Array.Internals.Operator.Compact as A
import Data.Repa.Array.Internals.Operator.Filter as A
import Data.Repa.Array.Internals.Operator.Fold as A
import Data.Repa.Array.Internals.Operator.Group as A
import Data.Repa.Array.Internals.Operator.Insert as A
import Data.Repa.Array.Internals.Operator.Merge as A
import Data.Repa.Array.Internals.Operator.Process as A
import Data.Repa.Array.Internals.Operator.Reduce as A
import Data.Repa.Array.Internals.Operator.Replicate as A
import qualified Data.Repa.Array.Generic.Convert as A
import qualified Data.Vector.Fusion.Stream.Monadic as V
import Control.Monad
import Prelude
hiding ( reverse, length, map, zipWith, concat, unlines
, foldl, sum, product, last
, filter)
#include "repa-array.h"
-- | O(len src) Yield `Just` the index of the first element matching the predicate
-- or `Nothing` if no such element exists.
findIndex :: BulkI l a
=> (a -> Bool) -> Array l a -> Maybe Int
findIndex p !arr
= loop_findIndex V.SPEC 0
where
!len = size (extent $ layout arr)
loop_findIndex !sPEC !ix
| ix >= len = Nothing
| otherwise
= let !x = arr `index` ix
in if p x then Just ix
else loop_findIndex sPEC (ix + 1)
{-# INLINE_INNER loop_findIndex #-}
{-# INLINE_ARRAY findIndex #-}
-- | Like `A.map`, but immediately `computeS` the result.
mapS :: (Bulk lSrc a, Target lDst b, Index lSrc ~ Index lDst)
=> Name lDst -- ^ Name of destination layout.
-> (a -> b) -- ^ Worker function.
-> Array lSrc a -- ^ Source array.
-> Array lDst b
mapS l f !xs = computeS l $! map f xs
{-# INLINE mapS #-}
-- | Like `A.map2`, but immediately `computeS` the result.
map2S :: (Bulk lSrc1 a, Bulk lSrc2 b, Target lDst c
, Index lSrc1 ~ Index lDst
, Index lSrc2 ~ Index lDst)
=> Name lDst -- ^ Name of destination layout.
-> (a -> b -> c ) -- ^ Worker function.
-> Array lSrc1 a -- ^ Source array.
-> Array lSrc2 b -- ^ Source array
-> Maybe (Array lDst c)
map2S l f xs ys
= liftM (computeS l) $! map2 f xs ys
{-# INLINE map2S #-}
-- | O(1). Constant time conversion of one array representation to another.
convert :: A.Convert l1 a1 l2 a2
=> Name l2 -> Array l1 a1 -> Array l2 a2
convert _ = A.convert
{-# INLINE convert #-}
-- | O(n). Linear time copy of one array representation to another.
--
-- This function must be used instead of `convert` when the bit-wise
-- layout of the two array representations are different.
--
copy :: (Bulk l1 a, Target l2 a, Index l1 ~ Index l2)
=> Name l2 -> Array l1 a -> Array l2 a
copy n2 arr = computeS n2 $! delay arr
{-# INLINE copy #-}