module Data.Repa.Array.Internals.Operator.Reduce
( foldl
, product, sum
, mean, std
, correlate)
where
import Data.Repa.Array.Generic.Index as A
import Data.Repa.Array.Meta.Delayed as A
import Data.Repa.Array.Meta.Tuple as A
import Data.Repa.Array.Internals.Bulk as A
import Data.Repa.Eval.Stream as A
import qualified Data.Vector.Fusion.Stream as S
import Prelude
as P hiding (foldl, sum, product)
#include "repa-array.h"
foldl :: (Bulk l b, Index l ~ Int)
=> (a -> b -> a) -> a -> Array l b -> a
foldl f z arr
= S.foldl' f z
$ streamOfArray arr
sum :: (BulkI l a, Num a) => Array l a -> a
sum arr = foldl (+) 0 arr
product :: (BulkI l a, Num a) => Array l a -> a
product arr = foldl (*) 1 arr
mean :: (BulkI l a, Fractional a)
=> Array l a -> a
mean arr = sum arr / fromIntegral (A.length arr)
std :: (BulkI l a, Floating a)
=> Array l a -> a
std arr
= let !u = mean arr
in sqrt $ mean $ A.map (\x -> (x u) ^ (2 :: Int)) arr
correlate
:: ( BulkI l1 a, BulkI l2 a
, Floating a)
=> Array l1 a
-> Array l2 a
-> a
correlate arr1 arr2
= let
(sX, sX2, sY, sY2, sXY)
= foldl (\ ( sXa, sX2a, sYa, sY2a, sXYa) (x, y)
-> ( sXa + x, sX2a + (x * x)
, sYa + y, sY2a + (y * y)
, sXYa + (x * y)))
(0, 0, 0, 0, 0)
$ tup2 arr1 arr2
!n = min (A.length arr1) (A.length arr2)
!n' = fromIntegral n
!corr = (/) ((n' * sXY) (sX * sY))
((*) (sqrt ((n' * sX2) (sX * sX)))
(sqrt ((n' * sY2) (sY * sY))))
in corr