repa-algorithms 2.2.0.1 → 3.0.0.1
raw patch · 13 files changed
+395/−185 lines, 13 filesdep ~repaPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: repa
API changes (from Hackage documentation)
- Data.Array.Repa.Algorithms.Complex: instance Fractional Complex
- Data.Array.Repa.Algorithms.Complex: instance Num Complex
- Data.Array.Repa.Algorithms.FFT: instance Eq Mode
- Data.Array.Repa.Algorithms.FFT: instance Show Mode
- Data.Array.Repa.Algorithms.Iterate: iterateBlockwise :: (Elt a, Num a) => Int -> (Array DIM2 a -> Array DIM2 a) -> Array DIM2 a -> Array DIM2 a
- Data.Array.Repa.Algorithms.Iterate: iterateBlockwise' :: (Elt a, Num a) => Int -> Array DIM2 a -> (Array DIM2 a -> Array DIM2 a) -> Array DIM2 a
- Data.Array.Repa.Algorithms.Matrix: multiplyMM :: Array DIM2 Double -> Array DIM2 Double -> Array DIM2 Double
+ Data.Array.Repa.Algorithms.ColorRamp: rampColorHotToCold :: (Ord a, Floating a) => a -> a -> a -> (a, a, a)
+ Data.Array.Repa.Algorithms.Complex: instance [overlap ok] Fractional Complex
+ Data.Array.Repa.Algorithms.Complex: instance [overlap ok] Num Complex
+ Data.Array.Repa.Algorithms.FFT: instance [overlap ok] Eq Mode
+ Data.Array.Repa.Algorithms.FFT: instance [overlap ok] Show Mode
+ Data.Array.Repa.Algorithms.Matrix: col :: DIM2 -> Int
+ Data.Array.Repa.Algorithms.Matrix: mmultP :: Array U DIM2 Double -> Array U DIM2 Double -> Array U DIM2 Double
+ Data.Array.Repa.Algorithms.Matrix: mmultS :: Array U DIM2 Double -> Array U DIM2 Double -> Array U DIM2 Double
+ Data.Array.Repa.Algorithms.Matrix: row :: DIM2 -> Int
+ Data.Array.Repa.Algorithms.Matrix: transpose2P :: Array U DIM2 Double -> Array U DIM2 Double
+ Data.Array.Repa.Algorithms.Matrix: transpose2S :: Array U DIM2 Double -> Array U DIM2 Double
+ Data.Array.Repa.Algorithms.Pixel: doubleLuminanceOfRGB8 :: (Word8, Word8, Word8) -> Double
+ Data.Array.Repa.Algorithms.Pixel: doubleRmsOfRGB8 :: (Word8, Word8, Word8) -> Float
+ Data.Array.Repa.Algorithms.Pixel: floatLuminanceOfRGB8 :: (Word8, Word8, Word8) -> Float
+ Data.Array.Repa.Algorithms.Pixel: floatRmsOfRGB8 :: (Word8, Word8, Word8) -> Float
+ Data.Array.Repa.Algorithms.Pixel: rgb8OfDouble :: (Double, Double, Double) -> (Word8, Word8, Word8)
+ Data.Array.Repa.Algorithms.Pixel: rgb8OfFloat :: (Float, Float, Float) -> (Word8, Word8, Word8)
+ Data.Array.Repa.Algorithms.Pixel: rgb8OfGreyDouble :: Double -> (Word8, Word8, Word8)
+ Data.Array.Repa.Algorithms.Pixel: rgb8OfGreyFloat :: Float -> (Word8, Word8, Word8)
- Data.Array.Repa.Algorithms.Convolve: convolve :: (Elt a, Num a) => (DIM2 -> a) -> Array DIM2 a -> Array DIM2 a -> Array DIM2 a
+ Data.Array.Repa.Algorithms.Convolve: convolve :: (Num a, Unbox a) => (DIM2 -> a) -> Array U DIM2 a -> Array U DIM2 a -> Array U DIM2 a
- Data.Array.Repa.Algorithms.Convolve: convolveOut :: (Elt a, Num a) => GetOut a -> Array DIM2 a -> Array DIM2 a -> Array DIM2 a
+ Data.Array.Repa.Algorithms.Convolve: convolveOut :: (Num a, Unbox a) => GetOut a -> Array U DIM2 a -> Array U DIM2 a -> Array U DIM2 a
- Data.Array.Repa.Algorithms.DFT: dft :: Shape sh => Array (sh :. Int) Complex -> Array (sh :. Int) Complex
+ Data.Array.Repa.Algorithms.DFT: dft :: Shape sh => Array U (sh :. Int) Complex -> Array U (sh :. Int) Complex
- Data.Array.Repa.Algorithms.DFT: dftWithRoots :: Shape sh => Array (sh :. Int) Complex -> Array (sh :. Int) Complex -> Array (sh :. Int) Complex
+ Data.Array.Repa.Algorithms.DFT: dftWithRoots :: Shape sh => Array U (sh :. Int) Complex -> Array U (sh :. Int) Complex -> Array U (sh :. Int) Complex
- Data.Array.Repa.Algorithms.DFT: dftWithRootsSingle :: Shape sh => Array (sh :. Int) Complex -> Array (sh :. Int) Complex -> (sh :. Int) -> Complex
+ Data.Array.Repa.Algorithms.DFT: dftWithRootsSingle :: Shape sh => Array U (sh :. Int) Complex -> Array U (sh :. Int) Complex -> (sh :. Int) -> Complex
- Data.Array.Repa.Algorithms.DFT: idft :: Shape sh => Array (sh :. Int) Complex -> Array (sh :. Int) Complex
+ Data.Array.Repa.Algorithms.DFT: idft :: Shape sh => Array U (sh :. Int) Complex -> Array U (sh :. Int) Complex
- Data.Array.Repa.Algorithms.DFT.Center: center1d :: Array DIM1 Complex -> Array DIM1 Complex
+ Data.Array.Repa.Algorithms.DFT.Center: center1d :: Repr r Complex => Array r DIM1 Complex -> Array D DIM1 Complex
- Data.Array.Repa.Algorithms.DFT.Center: center2d :: Array DIM2 Complex -> Array DIM2 Complex
+ Data.Array.Repa.Algorithms.DFT.Center: center2d :: Repr r Complex => Array r DIM2 Complex -> Array D DIM2 Complex
- Data.Array.Repa.Algorithms.DFT.Center: center3d :: Array DIM3 Complex -> Array DIM3 Complex
+ Data.Array.Repa.Algorithms.DFT.Center: center3d :: Repr r Complex => Array r DIM3 Complex -> Array D DIM3 Complex
- Data.Array.Repa.Algorithms.DFT.Roots: calcInverseRootsOfUnity :: Shape sh => (sh :. Int) -> Array (sh :. Int) Complex
+ Data.Array.Repa.Algorithms.DFT.Roots: calcInverseRootsOfUnity :: Shape sh => (sh :. Int) -> Array U (sh :. Int) Complex
- Data.Array.Repa.Algorithms.DFT.Roots: calcRootsOfUnity :: Shape sh => (sh :. Int) -> Array (sh :. Int) Complex
+ Data.Array.Repa.Algorithms.DFT.Roots: calcRootsOfUnity :: Shape sh => (sh :. Int) -> Array U (sh :. Int) Complex
- Data.Array.Repa.Algorithms.FFT: fft1d :: Mode -> Array DIM1 Complex -> Array DIM1 Complex
+ Data.Array.Repa.Algorithms.FFT: fft1d :: Repr r Complex => Mode -> Array r DIM1 Complex -> Array U DIM1 Complex
- Data.Array.Repa.Algorithms.FFT: fft2d :: Mode -> Array DIM2 Complex -> Array DIM2 Complex
+ Data.Array.Repa.Algorithms.FFT: fft2d :: Repr r Complex => Mode -> Array r DIM2 Complex -> Array U DIM2 Complex
- Data.Array.Repa.Algorithms.FFT: fft3d :: Mode -> Array DIM3 Complex -> Array DIM3 Complex
+ Data.Array.Repa.Algorithms.FFT: fft3d :: Repr r Complex => Mode -> Array r DIM3 Complex -> Array U DIM3 Complex
- Data.Array.Repa.Algorithms.Randomish: randomishDoubleArray :: Shape sh => sh -> Double -> Double -> Int -> Array sh Double
+ Data.Array.Repa.Algorithms.Randomish: randomishDoubleArray :: Shape sh => sh -> Double -> Double -> Int -> Array U sh Double
- Data.Array.Repa.Algorithms.Randomish: randomishIntArray :: Shape sh => sh -> Int -> Int -> Int -> Array sh Int
+ Data.Array.Repa.Algorithms.Randomish: randomishIntArray :: Shape sh => sh -> Int -> Int -> Int -> Array U sh Int
Files
- Data/Array/Repa/Algorithms/ColorRamp.hs +49/−0
- Data/Array/Repa/Algorithms/Complex.hs +1/−1
- Data/Array/Repa/Algorithms/Convolve.hs +41/−28
- Data/Array/Repa/Algorithms/DFT.hs +14/−13
- Data/Array/Repa/Algorithms/DFT/Center.hs +9/−3
- Data/Array/Repa/Algorithms/DFT/Roots.hs +5/−4
- Data/Array/Repa/Algorithms/FFT.hs +56/−47
- Data/Array/Repa/Algorithms/Iterate.hs +0/−45
- Data/Array/Repa/Algorithms/Matrix.hs +89/−29
- Data/Array/Repa/Algorithms/Pixel.hs +98/−0
- Data/Array/Repa/Algorithms/Randomish.hs +5/−5
- LICENSE +1/−1
- repa-algorithms.cabal +27/−9
+ Data/Array/Repa/Algorithms/ColorRamp.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE RankNTypes #-}++-- | Hyprometric color ramps, for making pretty images from scalar data.+module Data.Array.Repa.Algorithms.ColorRamp+ (rampColorHotToCold)+where+++-- | Standard Hot to Cold hypsometric color ramp.+-- Color sequence is red, yellow, green, cyan, blue.+rampColorHotToCold + :: forall a+ . (Ord a, Floating a) + => a -- ^ Minimum value of range.+ -> a -- ^ Maximum value of range.+ -> a -- ^ Data value.+ -> (a, a, a)+ +{-# INLINE rampColorHotToCold #-}+rampColorHotToCold vmin vmax vNotNorm+ = let + v | vNotNorm < vmin = vmin+ | vNotNorm > vmax = vmax+ | otherwise = vNotNorm+ + dv = vmax - vmin ++ result | v < vmin + 0.25 * dv+ = ( 0+ , 4 * (v - vmin) / dv+ , 1.0)+ + | v < vmin + 0.5 * dv+ = ( 0+ , 1.0+ , 1 + 4 * (vmin + 0.25 * dv - v) / dv)+ + | v < vmin + 0.75 * dv+ = ( 4 * (v - vmin - 0.5 * dv) / dv+ , 1.0+ , 0.0)+ + | otherwise+ = ( 1.0+ , 1 + 4 * (vmin + 0.75 * dv - v) / dv+ , 0)+ + in result+
Data/Array/Repa/Algorithms/Complex.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE TypeOperators, TypeSynonymInstances, FlexibleInstances #-}-+{-# OPTIONS -fno-warn-orphans #-} -- | Strict complex doubles. module Data.Array.Repa.Algorithms.Complex ( Complex
Data/Array/Repa/Algorithms/Convolve.hs view
@@ -1,43 +1,55 @@ {-# LANGUAGE BangPatterns, PackageImports #-} {-# OPTIONS -Wall -fno-warn-missing-signatures -fno-warn-incomplete-patterns #-} --- | Old support for stencil based convolutions. ------ NOTE: This is slated to be merged with the new Stencil support in the next version--- of Repa. We'll still expose the `convolve` function though.+-- | Generic stencil based convolutions. +-- +-- If your stencil fits within a 7x7 tile and is known at compile-time then using+-- then using the built-in stencil support provided by the main Repa package will+-- be 5-10x faster. +-- +-- If you have a larger stencil, the coefficients are not statically known, +-- or need more complex boundary handling than provided by the built-in functions,+-- then use this version instead. -- module Data.Array.Repa.Algorithms.Convolve- ( convolve+ ( -- * Arbitrary boundary handling+ convolve + -- * Specialised boundary handling , GetOut , outAs , outClamp , convolveOut ) where import Data.Array.Repa as A+import Data.Array.Repa.Repr.Unboxed as A import qualified Data.Vector.Unboxed as V import qualified Data.Array.Repa.Shape as S import Prelude as P --- Plain Convolve ---------------------------------------------------------------------------------+-- Plain Convolve ------------------------------------------------------------- -- | Image-kernel convolution,--- which takes a function specifying what value to return when the kernel doesn't apply.+-- which takes a function specifying what value to return when the+-- kernel doesn't apply. convolve- :: (Elt a, Num a)- => (DIM2 -> a) -- ^ Use this function to get border elements where the kernel apply.- -> Array DIM2 a -- ^ Kernel to use in the convolution.- -> Array DIM2 a -- ^ Input image.- -> Array DIM2 a--{-# INLINE convolve #-}-convolve makeOut- kernel@(Array (_ :. krnHeight :. krnWidth) [Region RangeAll (GenManifest krnVec)])- image@(Array imgSh@(_ :. imgHeight :. imgWidth) [Region RangeAll (GenManifest imgVec)])+ :: (Num a, Unbox a)+ => (DIM2 -> a) -- ^ Function to get border elements when + -- the stencil does not apply.+ -> Array U DIM2 a -- ^ Stencil to use in the convolution.+ -> Array U DIM2 a -- ^ Input image.+ -> Array U DIM2 a +convolve makeOut kernel image = kernel `deepSeqArray` image `deepSeqArray` - force $ unsafeTraverse image id update+ computeP $ unsafeTraverse image id update where + (Z :. krnHeight :. krnWidth) = extent kernel+ krnVec = toUnboxed kernel+ + imgSh@(Z :. imgHeight :. imgWidth) = extent image+ imgVec = toUnboxed image+ !krnHeight2 = krnHeight `div` 2 !krnWidth2 = krnWidth `div` 2 @@ -75,6 +87,7 @@ krnZ = krnVec `V.unsafeIndex` krnCur here = imgZ * krnZ in integrate (acc + here) (x + 1) y (imgCur + 1) (krnCur + 1)+{-# INLINE convolve #-} -- Convolve Out -----------------------------------------------------------------------------------@@ -114,20 +127,20 @@ -- | Image-kernel convolution, -- which takes a function specifying what value to use for out-of-range elements. convolveOut- :: (Elt a, Num a)- => GetOut a -- ^ Use this fn to get out of range elements.- -> Array DIM2 a -- ^ Kernel- -> Array DIM2 a -- ^ Image- -> Array DIM2 a+ :: (Num a, Unbox a)+ => GetOut a -- ^ How to handle out-of-range elements.+ -> Array U DIM2 a -- ^ Stencil to use in the convolution.+ -> Array U DIM2 a -- ^ Input image.+ -> Array U DIM2 a {-# INLINE convolveOut #-}-convolveOut getOut- kernel@(Array krnSh@(_ :. krnHeight :. krnWidth) _)- image@(Array imgSh@(_ :. imgHeight :. imgWidth) _)-+convolveOut getOut kernel image = kernel `deepSeqArray` image `deepSeqArray` - force $ unsafeTraverse image id stencil+ computeP $ unsafeTraverse image id stencil where + krnSh@(Z :. krnHeight :. krnWidth) = extent kernel + imgSh@(Z :. imgHeight :. imgWidth) = extent image+ !krnHeight2 = krnHeight `div` 2 !krnWidth2 = krnWidth `div` 2 !krnSize = S.size krnSh
Data/Array/Repa/Algorithms/DFT.hs view
@@ -24,28 +24,29 @@ import Data.Array.Repa as A import Prelude as P + -- | Compute the DFT along the low order dimension of an array. dft :: forall sh . Shape sh- => Array (sh :. Int) Complex- -> Array (sh :. Int) Complex+ => Array U (sh :. Int) Complex+ -> Array U (sh :. Int) Complex dft v = let rofu = calcRootsOfUnity (extent v)- in force $ dftWithRoots rofu v+ in dftWithRoots rofu v -- | Compute the inverse DFT along the low order dimension of an array. idft :: forall sh . Shape sh- => Array (sh :. Int) Complex- -> Array (sh :. Int) Complex+ => Array U (sh :. Int) Complex+ -> Array U (sh :. Int) Complex idft v = let _ :. len = extent v scale = (fromIntegral len, 0) rofu = calcInverseRootsOfUnity (extent v)- in force $ A.map (/ scale) $ dftWithRoots rofu v+ in computeP $ A.map (/ scale) $ dftWithRoots rofu v -- | Generic function for computation of forward or inverse DFT.@@ -55,9 +56,9 @@ dftWithRoots :: forall sh . Shape sh- => Array (sh :. Int) Complex -- ^ Roots of unity.- -> Array (sh :. Int) Complex -- ^ Input array.- -> Array (sh :. Int) Complex+ => Array U (sh :. Int) Complex -- ^ Roots of unity.+ -> Array U (sh :. Int) Complex -- ^ Input array.+ -> Array U (sh :. Int) Complex dftWithRoots rofu arr | _ :. rLen <- extent rofu@@ -67,7 +68,7 @@ P.++ " does not match the length of the roots (" P.++ show rLen P.++ ")" | otherwise- = traverse arr id (\_ k -> dftWithRootsSingle rofu arr k)+ = computeP $ traverse arr id (\_ k -> dftWithRootsSingle rofu arr k) -- | Compute a single value of the DFT.@@ -75,8 +76,8 @@ dftWithRootsSingle :: forall sh . Shape sh- => Array (sh :. Int) Complex -- ^ Roots of unity.- -> Array (sh :. Int) Complex -- ^ Input array.+ => Array U (sh :. Int) Complex -- ^ Roots of unity.+ -> Array U (sh :. Int) Complex -- ^ Input array. -> (sh :. Int) -- ^ Index of the value we want. -> Complex @@ -96,6 +97,6 @@ elemFn (sh' :. n) = rofu ! (sh' :. (k * n) `mod` len) - in A.sumAll $ A.zipWith (*) arrX wroots+ in A.sumAllP $ A.zipWith (*) arrX wroots
Data/Array/Repa/Algorithms/DFT/Center.hs view
@@ -10,7 +10,9 @@ import Data.Array.Repa.Algorithms.Complex -- | Apply the centering transform to a vector.-center1d :: Array DIM1 Complex -> Array DIM1 Complex+center1d+ :: Repr r Complex+ => Array r DIM1 Complex -> Array D DIM1 Complex {-# INLINE center1d #-} center1d arr = traverse arr id@@ -18,7 +20,9 @@ -- | Apply the centering transform to a matrix.-center2d :: Array DIM2 Complex -> Array DIM2 Complex+center2d+ :: Repr r Complex+ => Array r DIM2 Complex -> Array D DIM2 Complex {-# INLINE center2d #-} center2d arr = traverse arr id@@ -26,7 +30,9 @@ -- | Apply the centering transform to a 3d array.-center3d :: Array DIM3 Complex -> Array DIM3 Complex+center3d + :: Repr r Complex+ => Array r DIM3 Complex -> Array D DIM3 Complex {-# INLINE center3d #-} center3d arr = traverse arr id
Data/Array/Repa/Algorithms/DFT/Roots.hs view
@@ -8,15 +8,16 @@ import Data.Array.Repa import Data.Array.Repa.Algorithms.Complex + -- | Calculate roots of unity for the forward transform. calcRootsOfUnity :: forall sh . Shape sh => (sh :. Int) -- ^ Length of lowest dimension of result.- -> Array (sh :. Int) Complex+ -> Array U (sh :. Int) Complex calcRootsOfUnity sh@(_ :. n) - = force $ fromFunction sh f+ = computeP $ fromFunction sh f where f :: Shape sh => (sh :. Int) -> Complex f (_ :. i) @@ -31,10 +32,10 @@ :: forall sh . Shape sh => (sh :. Int) -- ^ Length of lowest dimension of result.- -> Array (sh :. Int) Complex+ -> Array U (sh :. Int) Complex calcInverseRootsOfUnity sh@(_ :. n) - = force $ fromFunction sh f+ = computeP $ fromFunction sh f where f :: Shape sh => (sh :. Int) -> Complex f (_ :. i)
Data/Array/Repa/Algorithms/FFT.hs view
@@ -18,12 +18,14 @@ import Data.Array.Repa as A import Prelude as P + data Mode = Forward | Reverse | Inverse deriving (Show, Eq) + {-# INLINE signOfMode #-} signOfMode :: Mode -> Double signOfMode mode@@ -43,14 +45,13 @@ | otherwise = False -- -- 3D Transform ----------------------------------------------------------------------------------- -- | Compute the DFT of a 3d array. Array dimensions must be powers of two else `error`.-fft3d :: Mode- -> Array DIM3 Complex- -> Array DIM3 Complex-+fft3d :: Repr r Complex+ => Mode+ -> Array r DIM3 Complex+ -> Array U DIM3 Complex+{-# INLINE fft3d #-} fft3d mode arr = let _ :. depth :. height :. width = extent arr !sign = signOfMode mode@@ -67,22 +68,25 @@ case mode of Forward -> fftTrans3d sign $ fftTrans3d sign $ fftTrans3d sign arr Reverse -> fftTrans3d sign $ fftTrans3d sign $ fftTrans3d sign arr- Inverse -> force $ A.map (/ scale) - $ fftTrans3d sign $ fftTrans3d sign $ fftTrans3d sign arr+ Inverse -> computeP+ $ A.map (/ scale) + $ fftTrans3d sign $ fftTrans3d sign $ fftTrans3d sign arr fftTrans3d - :: Double- -> Array DIM3 Complex - -> Array DIM3 Complex+ :: Repr r Complex+ => Double+ -> Array r DIM3 Complex + -> Array U DIM3 Complex -{-# NOINLINE fftTrans3d #-}-fftTrans3d sign arr'- = let arr = force arr'- (sh :. len) = extent arr- in force $ rotate3d $ fft sign sh len arr+{-# INLINE fftTrans3d #-}+fftTrans3d sign arr+ = let (sh :. len) = extent arr+ in computeP $ rotate3d $ fft sign sh len arr -rotate3d :: Array DIM3 Complex -> Array DIM3 Complex+rotate3d + :: Repr r Complex+ => Array r DIM3 Complex -> Array D DIM3 Complex {-# INLINE rotate3d #-} rotate3d arr = backpermute (sh :. m :. k :. l) f arr@@ -93,10 +97,11 @@ -- Matrix Transform ------------------------------------------------------------------------------- -- | Compute the DFT of a matrix. Array dimensions must be powers of two else `error`.-fft2d :: Mode- -> Array DIM2 Complex- -> Array DIM2 Complex-+fft2d :: Repr r Complex+ => Mode+ -> Array r DIM2 Complex+ -> Array U DIM2 Complex+{-# INLINE fft2d #-} fft2d mode arr = let _ :. height :. width = extent arr sign = signOfMode mode@@ -112,26 +117,27 @@ case mode of Forward -> fftTrans2d sign $ fftTrans2d sign arr Reverse -> fftTrans2d sign $ fftTrans2d sign arr- Inverse -> force $ A.map (/ scale) $ fftTrans2d sign $ fftTrans2d sign arr+ Inverse -> computeP $ A.map (/ scale) $ fftTrans2d sign $ fftTrans2d sign arr fftTrans2d - :: Double- -> Array DIM2 Complex - -> Array DIM2 Complex+ :: Repr r Complex+ => Double+ -> Array r DIM2 Complex + -> Array U DIM2 Complex -{-# NOINLINE fftTrans2d #-}-fftTrans2d sign arr'- = let arr = force arr'- (sh :. len) = extent arr- in force $ transpose $ fft sign sh len arr+{-# INLINE fftTrans2d #-}+fftTrans2d sign arr+ = let (sh :. len) = extent arr+ in computeP $ transpose $ fft sign sh len arr -- Vector Transform ------------------------------------------------------------------------------- -- | Compute the DFT of a vector. Array dimensions must be powers of two else `error`.-fft1d :: Mode - -> Array DIM1 Complex - -> Array DIM1 Complex- +fft1d :: Repr r Complex+ => Mode + -> Array r DIM1 Complex + -> Array U DIM1 Complex+{-# INLINE fft1d #-} fft1d mode arr = let _ :. len = extent arr sign = signOfMode mode@@ -147,27 +153,32 @@ case mode of Forward -> fftTrans1d sign arr Reverse -> fftTrans1d sign arr- Inverse -> force $ A.map (/ scale) $ fftTrans1d sign arr+ Inverse -> computeP $ A.map (/ scale) $ fftTrans1d sign arr fftTrans1d- :: Double - -> Array DIM1 Complex- -> Array DIM1 Complex+ :: Repr r Complex+ => Double + -> Array r DIM1 Complex+ -> Array U DIM1 Complex -{-# NOINLINE fftTrans1d #-}-fftTrans1d sign arr'- = let arr = force arr'- (sh :. len) = extent arr+{-# INLINE fftTrans1d #-}+fftTrans1d sign arr+ = let (sh :. len) = extent arr in fft sign sh len arr -- Rank Generalised Worker ------------------------------------------------------------------------+fft :: (Shape sh, Repr r Complex)+ => Double -> sh -> Int + -> Array r (sh :. Int) Complex+ -> Array U (sh :. Int) Complex+ {-# INLINE fft #-} fft !sign !sh !lenVec !vec = go lenVec 0 1 where go !len !offset !stride | len == 2- = force $ fromFunction (sh :. 2) swivel+ = computeP $ fromFunction (sh :. 2) swivel | otherwise = combine len @@ -180,11 +191,10 @@ 1 -> (vec `unsafeIndex` (sh' :. offset)) - (vec `unsafeIndex` (sh' :. (offset + stride))) {-# INLINE combine #-}- combine !len' evens@(Array _ [Region RangeAll GenManifest{}]) - odds@(Array _ [Region RangeAll GenManifest{}])+ combine !len' evens odds = evens `deepSeqArray` odds `deepSeqArray` let odds' = unsafeTraverse odds id (\get ix@(_ :. k) -> twiddle sign k len' * get ix) - in force $ (evens +^ odds') A.++ (evens -^ odds')+ in computeP $ (evens +^ odds') A.++ (evens -^ odds') -- Compute a twiddle factor.@@ -198,4 +208,3 @@ = (cos (2 * pi * k / n), sign * sin (2 * pi * k / n)) where k = fromIntegral k' n = fromIntegral n'-
− Data/Array/Repa/Algorithms/Iterate.hs
@@ -1,45 +0,0 @@-{-# LANGUAGE BangPatterns, PackageImports #-}-{-# OPTIONS -Wall -fno-warn-missing-signatures -fno-warn-incomplete-patterns #-}-module Data.Array.Repa.Algorithms.Iterate- (iterateBlockwise, iterateBlockwise')-where-import Data.Array.Repa---- | Iterate array transformation function a fixed number of times, applying `force2` between--- each iteration.-iterateBlockwise- :: (Elt a, Num a)- => Int -- ^ Number of iterations to run for.- -> (Array DIM2 a -> Array DIM2 a) -- ^ Fn to step the array.- -> Array DIM2 a -- ^ Initial array value.- -> Array DIM2 a- -{-# INLINE iterateBlockwise #-}-iterateBlockwise steps f arrInit@(Array shInit [Region RangeAll (GenManifest vecInit)])- = arrInit `deepSeqArray`- goSolve steps shInit vecInit-- where -- NOTE: We manually unpack the current array into its shape and vector to- -- stop GHC from unboxing the vector again for every loop. deepSeqing- -- the arrays at the start of solveLaplace makes the unboxings happen- -- at that point in the corresponding core code.- goSolve !i !shCurrent !vecCurrent- = let !arrCurrent = fromVector shCurrent vecCurrent- in if i == 0 - then arrCurrent- else let arrNew@(Array _ [Region RangeAll (GenManifest _)]) - = force2 $ f arrCurrent- in goSolve (i - 1) (extent arrNew) (toVector arrNew)----- | As above, but with the parameters flipped.-iterateBlockwise'- :: (Elt a, Num a)- => Int -- ^ Number of iterations to run for.- -> Array DIM2 a -- ^ Initial array value.- -> (Array DIM2 a -> Array DIM2 a) -- ^ Fn to step the array.- -> Array DIM2 a--{-# INLINE iterateBlockwise' #-}-iterateBlockwise' steps arr fn- = iterateBlockwise steps fn arr
Data/Array/Repa/Algorithms/Matrix.hs view
@@ -4,38 +4,98 @@ -- | Algorithms operating on matrices. -- -- These functions should give performance comparable with nested loop C--- implementations, but not block-based, cache friendly, SIMD using, vendor--- optimised implementions. --- If you care deeply about runtime performance then you may be better off using --- a binding to LAPACK, such as hvector.+-- implementations. +-- +-- If you care deeply about runtime performance then you+-- may be better off using a binding to LAPACK, such as hvector. -- module Data.Array.Repa.Algorithms.Matrix- (multiplyMM)+ ( -- * Projections+ row+ , col++ -- * Matrix Multiplication.+ , mmultP, mmultS++ -- * Transposition.+ , transpose2P, transpose2S) where-import Data.Array.Repa as A+import Data.Array.Repa as R --- | Matrix-matrix multiply.-multiplyMM- :: Array DIM2 Double- -> Array DIM2 Double- -> Array DIM2 Double -{-# NOINLINE multiplyMM #-}-multiplyMM arr@(Array _ [Region RangeAll (GenManifest _)])- brr@(Array _ [Region RangeAll (GenManifest _)])- = [arr, brr] `deepSeqArrays`- A.force $ A.sum (A.zipWith (*) arrRepl brrRepl)- where trr@(Array _ [Region RangeAll (GenManifest _)])- = force $ transpose2D brr- arrRepl = trr `deepSeqArray` A.extend (Z :. All :. colsB :. All) arr- brrRepl = trr `deepSeqArray` A.extend (Z :. rowsA :. All :. All) trr- (Z :. _ :. rowsA) = extent arr- (Z :. colsB :. _ ) = extent brr- +-- Projections ----------------------------------------------------------------+-- | Take the row number of a rank-2 index.+row :: DIM2 -> Int+row (Z :. r :. _) = r+{-# INLINE row #-} -transpose2D :: Elt e => Array DIM2 e -> Array DIM2 e-{-# INLINE transpose2D #-}-transpose2D arr- = backpermute new_extent swap arr- where swap (Z :. i :. j) = Z :. j :. i- new_extent = swap (extent arr)++-- | Take the column number of a rank-2 index.+col :: DIM2 -> Int+col (Z :. _ :. c) = c+{-# INLINE col #-}+++-- MMult ----------------------------------------------------------------------+-- | Matrix matrix multiply, in parallel.+mmultP :: Array U DIM2 Double + -> Array U DIM2 Double + -> Array U DIM2 Double++mmultP arr' brr + = mmult' arr' (transpose2P brr) + where mmult' arr trr+ = trr `deepSeqArray` computeP+ $ fromFunction (extent arr)+ $ \ix -> R.sumAllS + $ R.zipWith (*)+ (slice arr (Any :. (row ix) :. All))+ (slice trr (Any :. (col ix) :. All))+{-# NOINLINE mmultP #-}+++-- | Matrix matrix multiply, sequentially.+mmultS :: Array U DIM2 Double + -> Array U DIM2 Double + -> Array U DIM2 Double++mmultS arr' brr + = mmult' arr' (transpose2S brr) + where mmult' arr trr+ = trr `deepSeqArray` computeS+ $ fromFunction (extent arr)+ $ \ix -> R.sumAllS + $ R.zipWith (*)+ (slice arr (Any :. (row ix) :. All))+ (slice trr (Any :. (col ix) :. All))+{-# NOINLINE mmultS #-}+++-- Transpose ------------------------------------------------------------------+-- | Transpose a 2D matrix, in parallel.+transpose2P+ :: Array U DIM2 Double + -> Array U DIM2 Double++transpose2P arr+ = arr `deepSeqArray`+ computeUnboxedP+ $ unsafeBackpermute new_extent swap arr+ where swap (Z :. i :. j) = Z :. j :. i+ new_extent = swap (extent arr)+{-# NOINLINE transpose2P #-}+++-- | Transpose a 2D matrix, sequentially.+transpose2S+ :: Array U DIM2 Double + -> Array U DIM2 Double++transpose2S arr+ = arr `deepSeqArray`+ computeUnboxedS+ $ unsafeBackpermute new_extent swap arr+ where swap (Z :. i :. j) = Z :. j :. i+ new_extent = swap (extent arr)+{-# NOINLINE transpose2S #-}+
+ Data/Array/Repa/Algorithms/Pixel.hs view
@@ -0,0 +1,98 @@++-- | Utilities for converting pixel color values.+--+-- NOTE: These functions are not polymorphic in the Float type because+-- without assisatance, GHC does a bad job of converting Word8s +-- to and from floats. +--+module Data.Array.Repa.Algorithms.Pixel+ ( floatRmsOfRGB8+ , doubleRmsOfRGB8+ , floatLuminanceOfRGB8+ , doubleLuminanceOfRGB8+ , rgb8OfGreyFloat+ , rgb8OfGreyDouble+ , rgb8OfFloat+ , rgb8OfDouble)+where+import Data.Word+++-- | Compute the root mean square of an RGB color. Result is in the range [0..1].+floatRmsOfRGB8 :: (Word8, Word8, Word8) -> Float+{-# INLINE floatRmsOfRGB8 #-}+floatRmsOfRGB8 (r, g, b)+ = let r' = fromIntegral (fromIntegral r :: Int) / 255+ g' = fromIntegral (fromIntegral g :: Int) / 255+ b' = fromIntegral (fromIntegral b :: Int) / 255+ s = ((r' * r') + (g' * g') + (b' * b')) / 3+ in sqrt s+++-- | Compute the root mean square of an RGB color. Result is in the range [0..1].+doubleRmsOfRGB8 :: (Word8, Word8, Word8) -> Float+{-# INLINE doubleRmsOfRGB8 #-}+doubleRmsOfRGB8 (r, g, b)+ = let r' = fromIntegral (fromIntegral r :: Int) / 255+ g' = fromIntegral (fromIntegral g :: Int) / 255+ b' = fromIntegral (fromIntegral b :: Int) / 255+ s = ((r' * r') + (g' * g') + (b' * b')) / 3+ in sqrt s+++-- | Convert an RGB color to its luminance value. Result in the range [0..1].+floatLuminanceOfRGB8 :: (Word8, Word8, Word8) -> Float+{-# INLINE floatLuminanceOfRGB8 #-}+floatLuminanceOfRGB8 (r, g, b)+ = let r' = fromIntegral (fromIntegral r :: Int) / 255+ g' = fromIntegral (fromIntegral g :: Int) / 255+ b' = fromIntegral (fromIntegral b :: Int) / 255+ in r' * 0.3 + g' * 0.59 + b' * 0.11+++-- | Convert an RGB color to its luminance value. Result in the range [0..1].+doubleLuminanceOfRGB8 :: (Word8, Word8, Word8) -> Double+{-# INLINE doubleLuminanceOfRGB8 #-}+doubleLuminanceOfRGB8 (r, g, b)+ = let r' = fromIntegral (fromIntegral r :: Int) / 255+ g' = fromIntegral (fromIntegral g :: Int) / 255+ b' = fromIntegral (fromIntegral b :: Int) / 255+ in r' * 0.3 + g' * 0.59 + b' * 0.11+++-- | Promote a value in the range [0..1] to a grey RGB8 color.+rgb8OfGreyFloat :: Float -> (Word8, Word8, Word8)+{-# INLINE rgb8OfGreyFloat #-}+rgb8OfGreyFloat x+ = let v = fromIntegral (truncate (x * 255) :: Int)+ in (v, v, v)+++-- | Promote a value in the range [0..1] to a grey RGB8 color.+rgb8OfGreyDouble :: Double -> (Word8, Word8, Word8)+{-# INLINE rgb8OfGreyDouble #-}+rgb8OfGreyDouble x+ = let v = fromIntegral (truncate (x * 255) :: Int)+ in (v, v, v)+++-- | Promote a tuple of color components to a RGB8 color. +-- Each of the source components should be in the range [0..1].+rgb8OfFloat :: (Float, Float, Float) -> (Word8, Word8, Word8)+{-# INLINE rgb8OfFloat #-}+rgb8OfFloat (r, g, b)+ = let r8 = fromIntegral (truncate (r * 255) :: Int)+ g8 = fromIntegral (truncate (g * 255) :: Int)+ b8 = fromIntegral (truncate (b * 255) :: Int)+ in (r8, g8, b8)+++-- | Promote a tuple of color components to a RGB8 color. +-- Each of the source components should be in the range [0..1].+rgb8OfDouble :: (Double, Double, Double) -> (Word8, Word8, Word8)+{-# INLINE rgb8OfDouble #-}+rgb8OfDouble (r, g, b)+ = let r8 = fromIntegral (truncate (r * 255) :: Int)+ g8 = fromIntegral (truncate (g * 255) :: Int)+ b8 = fromIntegral (truncate (b * 255) :: Int)+ in (r8, g8, b8)
Data/Array/Repa/Algorithms/Randomish.hs view
@@ -32,10 +32,10 @@ -> Int -- ^ Minumum value in output. -> Int -- ^ Maximum value in output. -> Int -- ^ Random seed. - -> Array sh Int -- ^ Array of randomish numbers.+ -> Array U sh Int -- ^ Array of randomish numbers. randomishIntArray !sh !valMin !valMax !seed- = fromVector sh $ randomishIntVector (R.size sh) valMin valMax seed+ = fromUnboxed sh $ randomishIntVector (R.size sh) valMin valMax seed randomishIntVector @@ -90,10 +90,10 @@ -> Double -- ^ Minumum value in output. -> Double -- ^ Maximum value in output. -> Int -- ^ Random seed. - -> Array sh Double -- ^ Array of randomish numbers.+ -> Array U sh Double -- ^ Array of randomish numbers. randomishDoubleArray !sh !valMin !valMax !seed- = fromVector sh $ randomishDoubleVector (R.size sh) valMin valMax seed+ = fromUnboxed sh $ randomishDoubleVector (R.size sh) valMin valMax seed -- | Generate some randomish doubles with terrible statistical properties.@@ -109,7 +109,7 @@ = let range = valMax - valMin mx = 2^(30 :: Integer) - 1- mxf = fromIntegral mx+ mxf = fromIntegral (mx :: Integer) ints = randomishIntVector len 0 mx seed in V.map (\n -> valMin + (fromIntegral n / mxf) * range) ints
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2010, University of New South Wales.+Copyright (c) 2010-2012, University of New South Wales. All rights reserved. Redistribution and use in source and binary forms, with or without
repa-algorithms.cabal view
@@ -1,5 +1,5 @@ Name: repa-algorithms-Version: 2.2.0.1+Version: 3.0.0.1 License: BSD3 License-file: LICENSE Author: The DPH Team@@ -20,24 +20,42 @@ Build-Depends: base == 4.*, vector == 0.9.*,- repa == 2.2.*+ repa == 3.0.* ghc-options: -Wall -fno-warn-missing-signatures -Odph+ -fno-liberate-case -fsimplifier-phases=4- -fstrictness-before=5- -funfolding-use-threshold=30+ -funfolding-use-threshold=1000+ -funfolding-keeness-factor=1000 -funbox-strict-fields -fcpr-off+ -fllvm+ -optlo-O3 + extensions:+ NoMonomorphismRestriction+ ExplicitForAll+ EmptyDataDecls+ BangPatterns+ TypeFamilies+ MultiParamTypeClasses+ FlexibleInstances+ FlexibleContexts+ StandaloneDeriving+ ScopedTypeVariables+ PatternGuards+ OverlappingInstances+ Exposed-modules:+ Data.Array.Repa.Algorithms.DFT.Center+ Data.Array.Repa.Algorithms.DFT.Roots+ Data.Array.Repa.Algorithms.ColorRamp Data.Array.Repa.Algorithms.Complex- Data.Array.Repa.Algorithms.Randomish+ Data.Array.Repa.Algorithms.Convolve Data.Array.Repa.Algorithms.DFT- Data.Array.Repa.Algorithms.DFT.Roots- Data.Array.Repa.Algorithms.DFT.Center Data.Array.Repa.Algorithms.FFT Data.Array.Repa.Algorithms.Matrix- Data.Array.Repa.Algorithms.Convolve- Data.Array.Repa.Algorithms.Iterate+ Data.Array.Repa.Algorithms.Pixel+ Data.Array.Repa.Algorithms.Randomish