{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{- |
The functions in this module miss any bound checking.
-}
module Data.Array.Comfort.Storable.Unchecked (
   Priv.Array(Array, shape, buffer),
   Priv.reshape,
   mapShape,

   (Priv.!),
   unsafeCreate,
   unsafeCreateWithSize,
   unsafeCreateWithSizeAndResult,
   Priv.toList,
   Priv.fromList,
   Priv.vectorFromList,

   map,
   mapWithIndex,
   zipWith,
   (Priv.//),
   Priv.accumulate,
   Priv.fromAssociations,

   singleton,
   append,
   take, drop,
   takeLeft, takeRight, split,
   takeCenter,

   sum, product,
   foldl,
   ) where

import qualified Data.Array.Comfort.Storable.Unchecked.Monadic as Monadic
import qualified Data.Array.Comfort.Storable.Private as Priv
import qualified Data.Array.Comfort.Storable.Memory as Memory
import qualified Data.Array.Comfort.Shape as Shape
import Data.Array.Comfort.Storable.Private (Array(Array), mapShape)
import Data.Array.Comfort.Shape ((:+:)((:+:)))

import System.IO.Unsafe (unsafePerformIO)
import Foreign.Marshal.Array (copyArray, advancePtr)
import Foreign.Storable (Storable, poke, peek)
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.Ptr (Ptr)

import Control.Monad.ST (runST)
import Control.Applicative (liftA2)

import qualified Data.List as List

import Prelude hiding (map, zipWith, foldl, take, drop, sum, product)


{- $setup
>>> import DocTest.Data.Array.Comfort.Storable (ShapeInt, genArray)
>>>
>>> import qualified Data.Array.Comfort.Storable as Array
>>> import qualified Data.Array.Comfort.Shape as Shape
>>> import Data.Array.Comfort.Storable (Array, (!))
>>>
>>> import qualified Test.QuickCheck as QC
>>>
>>> import Data.Word (Word16)
>>>
>>> newtype Array16 = Array16 (Array ShapeInt Word16)
>>>    deriving (Show)
>>>
>>> instance QC.Arbitrary Array16 where
>>>    arbitrary = fmap Array16 genArray
-}


unsafeCreate ::
   (Shape.C sh, Storable a) =>
   sh -> (Ptr a -> IO ()) -> Array sh a
unsafeCreate :: sh -> (Ptr a -> IO ()) -> Array sh a
unsafeCreate sh
sh Ptr a -> IO ()
arr = (forall s. ST s (Array sh a)) -> Array sh a
forall a. (forall s. ST s a) -> a
runST (sh -> (Ptr a -> IO ()) -> ST s (Array sh a)
forall (m :: * -> *) sh a.
(PrimMonad m, C sh, Storable a) =>
sh -> (Ptr a -> IO ()) -> m (Array sh a)
Monadic.unsafeCreate sh
sh Ptr a -> IO ()
arr)

unsafeCreateWithSize ::
   (Shape.C sh, Storable a) =>
   sh -> (Int -> Ptr a -> IO ()) -> Array sh a
unsafeCreateWithSize :: sh -> (Int -> Ptr a -> IO ()) -> Array sh a
unsafeCreateWithSize sh
sh Int -> Ptr a -> IO ()
arr = (forall s. ST s (Array sh a)) -> Array sh a
forall a. (forall s. ST s a) -> a
runST (sh -> (Int -> Ptr a -> IO ()) -> ST s (Array sh a)
forall (m :: * -> *) sh a.
(PrimMonad m, C sh, Storable a) =>
sh -> (Int -> Ptr a -> IO ()) -> m (Array sh a)
Monadic.unsafeCreateWithSize sh
sh Int -> Ptr a -> IO ()
arr)

unsafeCreateWithSizeAndResult ::
   (Shape.C sh, Storable a) =>
   sh -> (Int -> Ptr a -> IO b) -> (Array sh a, b)
unsafeCreateWithSizeAndResult :: sh -> (Int -> Ptr a -> IO b) -> (Array sh a, b)
unsafeCreateWithSizeAndResult sh
sh Int -> Ptr a -> IO b
arr =
   (forall s. ST s (Array sh a, b)) -> (Array sh a, b)
forall a. (forall s. ST s a) -> a
runST (sh -> (Int -> Ptr a -> IO b) -> ST s (Array sh a, b)
forall (m :: * -> *) sh a b.
(PrimMonad m, C sh, Storable a) =>
sh -> (Int -> Ptr a -> IO b) -> m (Array sh a, b)
Monadic.unsafeCreateWithSizeAndResult sh
sh Int -> Ptr a -> IO b
arr)


map ::
   (Shape.C sh, Storable a, Storable b) =>
   (a -> b) -> Array sh a -> Array sh b
map :: (a -> b) -> Array sh a -> Array sh b
map a -> b
f (Array sh
sh ForeignPtr a
a) =
   sh -> (Ptr b -> IO ()) -> Array sh b
forall sh a.
(C sh, Storable a) =>
sh -> (Ptr a -> IO ()) -> Array sh a
unsafeCreate sh
sh ((Ptr b -> IO ()) -> Array sh b) -> (Ptr b -> IO ()) -> Array sh b
forall a b. (a -> b) -> a -> b
$ \Ptr b
dstPtr ->
   ForeignPtr a -> (Ptr a -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
a ((Ptr a -> IO ()) -> IO ()) -> (Ptr a -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr a
srcPtr ->
   [IO ()] -> IO ()
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_ ([IO ()] -> IO ()) -> [IO ()] -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> [IO ()] -> [IO ()]
forall a. Int -> [a] -> [a]
List.take (sh -> Int
forall sh. C sh => sh -> Int
Shape.size sh
sh) ([IO ()] -> [IO ()]) -> [IO ()] -> [IO ()]
forall a b. (a -> b) -> a -> b
$
      (Ptr a -> Ptr b -> IO ()) -> [Ptr a] -> [Ptr b] -> [IO ()]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
List.zipWith
         (\Ptr a
src Ptr b
dst -> Ptr b -> b -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr b
dst (b -> IO ()) -> (a -> b) -> a -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f (a -> IO ()) -> IO a -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek Ptr a
src)
         ((Ptr a -> Ptr a) -> Ptr a -> [Ptr a]
forall a. (a -> a) -> a -> [a]
iterate ((Ptr a -> Int -> Ptr a) -> Int -> Ptr a -> Ptr a
forall a b c. (a -> b -> c) -> b -> a -> c
flip Ptr a -> Int -> Ptr a
forall a. Storable a => Ptr a -> Int -> Ptr a
advancePtr Int
1) Ptr a
srcPtr)
         ((Ptr b -> Ptr b) -> Ptr b -> [Ptr b]
forall a. (a -> a) -> a -> [a]
iterate ((Ptr b -> Int -> Ptr b) -> Int -> Ptr b -> Ptr b
forall a b c. (a -> b -> c) -> b -> a -> c
flip Ptr b -> Int -> Ptr b
forall a. Storable a => Ptr a -> Int -> Ptr a
advancePtr Int
1) Ptr b
dstPtr)

mapWithIndex ::
   (Shape.Indexed sh, Shape.Index sh ~ ix, Storable a, Storable b) =>
   (ix -> a -> b) -> Array sh a -> Array sh b
mapWithIndex :: (ix -> a -> b) -> Array sh a -> Array sh b
mapWithIndex ix -> a -> b
f (Array sh
sh ForeignPtr a
a) =
   sh -> (Ptr b -> IO ()) -> Array sh b
forall sh a.
(C sh, Storable a) =>
sh -> (Ptr a -> IO ()) -> Array sh a
unsafeCreate sh
sh ((Ptr b -> IO ()) -> Array sh b) -> (Ptr b -> IO ()) -> Array sh b
forall a b. (a -> b) -> a -> b
$ \Ptr b
dstPtr ->
   ForeignPtr a -> (Ptr a -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
a ((Ptr a -> IO ()) -> IO ()) -> (Ptr a -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr a
srcPtr ->
   [IO ()] -> IO ()
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_ ([IO ()] -> IO ()) -> [IO ()] -> IO ()
forall a b. (a -> b) -> a -> b
$
      (ix -> Ptr a -> Ptr b -> IO ())
-> [ix] -> [Ptr a] -> [Ptr b] -> [IO ()]
forall a b c d. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
List.zipWith3
         (\ix
ix Ptr a
src Ptr b
dst -> Ptr b -> b -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr b
dst (b -> IO ()) -> (a -> b) -> a -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ix -> a -> b
f ix
ix (a -> IO ()) -> IO a -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek Ptr a
src)
         (sh -> [Index sh]
forall sh. Indexed sh => sh -> [Index sh]
Shape.indices sh
sh)
         ((Ptr a -> Ptr a) -> Ptr a -> [Ptr a]
forall a. (a -> a) -> a -> [a]
iterate ((Ptr a -> Int -> Ptr a) -> Int -> Ptr a -> Ptr a
forall a b c. (a -> b -> c) -> b -> a -> c
flip Ptr a -> Int -> Ptr a
forall a. Storable a => Ptr a -> Int -> Ptr a
advancePtr Int
1) Ptr a
srcPtr)
         ((Ptr b -> Ptr b) -> Ptr b -> [Ptr b]
forall a. (a -> a) -> a -> [a]
iterate ((Ptr b -> Int -> Ptr b) -> Int -> Ptr b -> Ptr b
forall a b c. (a -> b -> c) -> b -> a -> c
flip Ptr b -> Int -> Ptr b
forall a. Storable a => Ptr a -> Int -> Ptr a
advancePtr Int
1) Ptr b
dstPtr)

zipWith ::
   (Shape.C sh, Storable a, Storable b, Storable c) =>
   (a -> b -> c) -> Array sh a -> Array sh b -> Array sh c
zipWith :: (a -> b -> c) -> Array sh a -> Array sh b -> Array sh c
zipWith a -> b -> c
f (Array sh
_sh ForeignPtr a
a) (Array sh
sh ForeignPtr b
b) =
   sh -> (Ptr c -> IO ()) -> Array sh c
forall sh a.
(C sh, Storable a) =>
sh -> (Ptr a -> IO ()) -> Array sh a
unsafeCreate sh
sh ((Ptr c -> IO ()) -> Array sh c) -> (Ptr c -> IO ()) -> Array sh c
forall a b. (a -> b) -> a -> b
$ \Ptr c
dstPtr ->
   ForeignPtr a -> (Ptr a -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
a ((Ptr a -> IO ()) -> IO ()) -> (Ptr a -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr a
srcAPtr ->
   ForeignPtr b -> (Ptr b -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr b
b ((Ptr b -> IO ()) -> IO ()) -> (Ptr b -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr b
srcBPtr ->
   [IO ()] -> IO ()
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_ ([IO ()] -> IO ()) -> [IO ()] -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> [IO ()] -> [IO ()]
forall a. Int -> [a] -> [a]
List.take (sh -> Int
forall sh. C sh => sh -> Int
Shape.size sh
sh) ([IO ()] -> [IO ()]) -> [IO ()] -> [IO ()]
forall a b. (a -> b) -> a -> b
$
      (Ptr a -> Ptr b -> Ptr c -> IO ())
-> [Ptr a] -> [Ptr b] -> [Ptr c] -> [IO ()]
forall a b c d. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3
         (\Ptr a
srcA Ptr b
srcB Ptr c
dst -> Ptr c -> c -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr c
dst (c -> IO ()) -> IO c -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (a -> b -> c) -> IO a -> IO b -> IO c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> b -> c
f (Ptr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek Ptr a
srcA) (Ptr b -> IO b
forall a. Storable a => Ptr a -> IO a
peek Ptr b
srcB))
         ((Ptr a -> Ptr a) -> Ptr a -> [Ptr a]
forall a. (a -> a) -> a -> [a]
iterate ((Ptr a -> Int -> Ptr a) -> Int -> Ptr a -> Ptr a
forall a b c. (a -> b -> c) -> b -> a -> c
flip Ptr a -> Int -> Ptr a
forall a. Storable a => Ptr a -> Int -> Ptr a
advancePtr Int
1) Ptr a
srcAPtr)
         ((Ptr b -> Ptr b) -> Ptr b -> [Ptr b]
forall a. (a -> a) -> a -> [a]
iterate ((Ptr b -> Int -> Ptr b) -> Int -> Ptr b -> Ptr b
forall a b c. (a -> b -> c) -> b -> a -> c
flip Ptr b -> Int -> Ptr b
forall a. Storable a => Ptr a -> Int -> Ptr a
advancePtr Int
1) Ptr b
srcBPtr)
         ((Ptr c -> Ptr c) -> Ptr c -> [Ptr c]
forall a. (a -> a) -> a -> [a]
iterate ((Ptr c -> Int -> Ptr c) -> Int -> Ptr c -> Ptr c
forall a b c. (a -> b -> c) -> b -> a -> c
flip Ptr c -> Int -> Ptr c
forall a. Storable a => Ptr a -> Int -> Ptr a
advancePtr Int
1) Ptr c
dstPtr)


{- |
prop> \x  ->  Array.singleton x ! () == (x::Word16)
-}
singleton :: (Storable a) => a -> Array () a
singleton :: a -> Array () a
singleton a
a = () -> (Ptr a -> IO ()) -> Array () a
forall sh a.
(C sh, Storable a) =>
sh -> (Ptr a -> IO ()) -> Array sh a
unsafeCreate () ((Ptr a -> IO ()) -> Array () a) -> (Ptr a -> IO ()) -> Array () a
forall a b. (a -> b) -> a -> b
$ (Ptr a -> a -> IO ()) -> a -> Ptr a -> IO ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip Ptr a -> a -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke a
a

append ::
   (Shape.C shx, Shape.C shy, Storable a) =>
   Array shx a -> Array shy a -> Array (shx:+:shy) a
append :: Array shx a -> Array shy a -> Array (shx :+: shy) a
append (Array shx
shX ForeignPtr a
x) (Array shy
shY ForeignPtr a
y) =
   (shx :+: shy) -> (Ptr a -> IO ()) -> Array (shx :+: shy) a
forall sh a.
(C sh, Storable a) =>
sh -> (Ptr a -> IO ()) -> Array sh a
unsafeCreate (shx
shXshx -> shy -> shx :+: shy
forall sh0 sh1. sh0 -> sh1 -> sh0 :+: sh1
:+:shy
shY) ((Ptr a -> IO ()) -> Array (shx :+: shy) a)
-> (Ptr a -> IO ()) -> Array (shx :+: shy) a
forall a b. (a -> b) -> a -> b
$ \Ptr a
zPtr ->
   ForeignPtr a -> (Ptr a -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
x ((Ptr a -> IO ()) -> IO ()) -> (Ptr a -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr a
xPtr ->
   ForeignPtr a -> (Ptr a -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
y ((Ptr a -> IO ()) -> IO ()) -> (Ptr a -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr a
yPtr -> do
      let sizeX :: Int
sizeX = shx -> Int
forall sh. C sh => sh -> Int
Shape.size shx
shX
      let sizeY :: Int
sizeY = shy -> Int
forall sh. C sh => sh -> Int
Shape.size shy
shY
      Ptr a -> Ptr a -> Int -> IO ()
forall a. Storable a => Ptr a -> Ptr a -> Int -> IO ()
copyArray Ptr a
zPtr Ptr a
xPtr Int
sizeX
      Ptr a -> Ptr a -> Int -> IO ()
forall a. Storable a => Ptr a -> Ptr a -> Int -> IO ()
copyArray (Ptr a -> Int -> Ptr a
forall a. Storable a => Ptr a -> Int -> Ptr a
advancePtr Ptr a
zPtr Int
sizeX) Ptr a
yPtr Int
sizeY

{- |
prop> \(QC.NonNegative n) (Array16 x)  ->  x == Array.mapShape (Shape.ZeroBased . Shape.size) (Array.append (Array.take n x) (Array.drop n x))
-}
take, drop ::
   (Integral n, Storable a) =>
   n -> Array (Shape.ZeroBased n) a -> Array (Shape.ZeroBased n) a
take :: n -> Array (ZeroBased n) a -> Array (ZeroBased n) a
take n
n = Array (ZeroBased n :+: ZeroBased n) a -> Array (ZeroBased n) a
forall sh0 sh1 a.
(C sh0, C sh1, Storable a) =>
Array (sh0 :+: sh1) a -> Array sh0 a
takeLeft (Array (ZeroBased n :+: ZeroBased n) a -> Array (ZeroBased n) a)
-> (Array (ZeroBased n) a -> Array (ZeroBased n :+: ZeroBased n) a)
-> Array (ZeroBased n) a
-> Array (ZeroBased n) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. n -> Array (ZeroBased n) a -> Array (ZeroBased n :+: ZeroBased n) a
forall n a.
(Integral n, Storable a) =>
n -> Array (ZeroBased n) a -> Array (ZeroBased n :+: ZeroBased n) a
splitN n
n
drop :: n -> Array (ZeroBased n) a -> Array (ZeroBased n) a
drop n
n = Array (ZeroBased n :+: ZeroBased n) a -> Array (ZeroBased n) a
forall sh0 sh1 a.
(C sh0, C sh1, Storable a) =>
Array (sh0 :+: sh1) a -> Array sh1 a
takeRight (Array (ZeroBased n :+: ZeroBased n) a -> Array (ZeroBased n) a)
-> (Array (ZeroBased n) a -> Array (ZeroBased n :+: ZeroBased n) a)
-> Array (ZeroBased n) a
-> Array (ZeroBased n) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. n -> Array (ZeroBased n) a -> Array (ZeroBased n :+: ZeroBased n) a
forall n a.
(Integral n, Storable a) =>
n -> Array (ZeroBased n) a -> Array (ZeroBased n :+: ZeroBased n) a
splitN n
n

splitN ::
   (Integral n, Storable a) =>
   n -> Array (Shape.ZeroBased n) a ->
   Array (Shape.ZeroBased n :+: Shape.ZeroBased n) a
splitN :: n -> Array (ZeroBased n) a -> Array (ZeroBased n :+: ZeroBased n) a
splitN n
n = (ZeroBased n -> ZeroBased n :+: ZeroBased n)
-> Array (ZeroBased n) a -> Array (ZeroBased n :+: ZeroBased n) a
forall sh0 sh1 a. (sh0 -> sh1) -> Array sh0 a -> Array sh1 a
mapShape (n -> ZeroBased n -> ZeroBased n :+: ZeroBased n
forall n. Real n => n -> ZeroBased n -> ZeroBased n :+: ZeroBased n
Shape.zeroBasedSplit n
n)

{- |
prop> \(Array16 x) (Array16 y) -> let xy = Array.append x y in x == Array.takeLeft xy  &&  y == Array.takeRight xy
-}
takeLeft ::
   (Shape.C sh0, Shape.C sh1, Storable a) =>
   Array (sh0:+:sh1) a -> Array sh0 a
takeLeft :: Array (sh0 :+: sh1) a -> Array sh0 a
takeLeft =
   Array (Zero :+: (sh0 :+: sh1)) a -> Array sh0 a
forall sh0 sh1 sh2 a.
(C sh0, C sh1, C sh2, Storable a) =>
Array (sh0 :+: (sh1 :+: sh2)) a -> Array sh1 a
takeCenter (Array (Zero :+: (sh0 :+: sh1)) a -> Array sh0 a)
-> (Array (sh0 :+: sh1) a -> Array (Zero :+: (sh0 :+: sh1)) a)
-> Array (sh0 :+: sh1) a
-> Array sh0 a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((sh0 :+: sh1) -> Zero :+: (sh0 :+: sh1))
-> Array (sh0 :+: sh1) a -> Array (Zero :+: (sh0 :+: sh1)) a
forall sh0 sh1 a. (sh0 -> sh1) -> Array sh0 a -> Array sh1 a
mapShape (\(sh0
sh0 :+: sh1
sh1) -> (Zero
Shape.Zero Zero -> (sh0 :+: sh1) -> Zero :+: (sh0 :+: sh1)
forall sh0 sh1. sh0 -> sh1 -> sh0 :+: sh1
:+: sh0
sh0 sh0 -> sh1 -> sh0 :+: sh1
forall sh0 sh1. sh0 -> sh1 -> sh0 :+: sh1
:+: sh1
sh1))

takeRight ::
   (Shape.C sh0, Shape.C sh1, Storable a) =>
   Array (sh0:+:sh1) a -> Array sh1 a
takeRight :: Array (sh0 :+: sh1) a -> Array sh1 a
takeRight =
   Array (sh0 :+: (sh1 :+: Zero)) a -> Array sh1 a
forall sh0 sh1 sh2 a.
(C sh0, C sh1, C sh2, Storable a) =>
Array (sh0 :+: (sh1 :+: sh2)) a -> Array sh1 a
takeCenter (Array (sh0 :+: (sh1 :+: Zero)) a -> Array sh1 a)
-> (Array (sh0 :+: sh1) a -> Array (sh0 :+: (sh1 :+: Zero)) a)
-> Array (sh0 :+: sh1) a
-> Array sh1 a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((sh0 :+: sh1) -> sh0 :+: (sh1 :+: Zero))
-> Array (sh0 :+: sh1) a -> Array (sh0 :+: (sh1 :+: Zero)) a
forall sh0 sh1 a. (sh0 -> sh1) -> Array sh0 a -> Array sh1 a
mapShape (\(sh0
sh0 :+: sh1
sh1) -> (sh0
sh0 sh0 -> (sh1 :+: Zero) -> sh0 :+: (sh1 :+: Zero)
forall sh0 sh1. sh0 -> sh1 -> sh0 :+: sh1
:+: sh1
sh1 sh1 -> Zero -> sh1 :+: Zero
forall sh0 sh1. sh0 -> sh1 -> sh0 :+: sh1
:+: Zero
Shape.Zero))

split ::
   (Shape.C sh0, Shape.C sh1, Storable a) =>
   Array (sh0:+:sh1) a -> (Array sh0 a, Array sh1 a)
split :: Array (sh0 :+: sh1) a -> (Array sh0 a, Array sh1 a)
split Array (sh0 :+: sh1) a
x = (Array (sh0 :+: sh1) a -> Array sh0 a
forall sh0 sh1 a.
(C sh0, C sh1, Storable a) =>
Array (sh0 :+: sh1) a -> Array sh0 a
takeLeft Array (sh0 :+: sh1) a
x, Array (sh0 :+: sh1) a -> Array sh1 a
forall sh0 sh1 a.
(C sh0, C sh1, Storable a) =>
Array (sh0 :+: sh1) a -> Array sh1 a
takeRight Array (sh0 :+: sh1) a
x)

{- |
prop> \(Array16 x) (Array16 y) (Array16 z) -> let xyz = Array.append x $ Array.append y z in y == Array.takeCenter xyz
-}
takeCenter ::
   (Shape.C sh0, Shape.C sh1, Shape.C sh2, Storable a) =>
   Array (sh0:+:sh1:+:sh2) a -> Array sh1 a
takeCenter :: Array (sh0 :+: (sh1 :+: sh2)) a -> Array sh1 a
takeCenter (Array (sh0
sh0:+:sh1
sh1:+:sh2
_sh2) ForeignPtr a
x) =
   sh1 -> (Int -> Ptr a -> IO ()) -> Array sh1 a
forall sh a.
(C sh, Storable a) =>
sh -> (Int -> Ptr a -> IO ()) -> Array sh a
unsafeCreateWithSize sh1
sh1 ((Int -> Ptr a -> IO ()) -> Array sh1 a)
-> (Int -> Ptr a -> IO ()) -> Array sh1 a
forall a b. (a -> b) -> a -> b
$ \Int
k Ptr a
yPtr ->
   ForeignPtr a -> (Ptr a -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
x ((Ptr a -> IO ()) -> IO ()) -> (Ptr a -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr a
xPtr ->
      Ptr a -> Ptr a -> Int -> IO ()
forall a. Storable a => Ptr a -> Ptr a -> Int -> IO ()
copyArray Ptr a
yPtr (Ptr a -> Int -> Ptr a
forall a. Storable a => Ptr a -> Int -> Ptr a
advancePtr Ptr a
xPtr (sh0 -> Int
forall sh. C sh => sh -> Int
Shape.size sh0
sh0)) Int
k



{- |
prop> \(Array16 xs)  ->  Array.sum xs == sum (Array.toList xs)
-}
sum :: (Shape.C sh, Storable a, Num a) => Array sh a -> a
sum :: Array sh a -> a
sum = (a -> a -> a) -> a -> Array sh a -> a
forall sh a b.
(C sh, Storable a) =>
(b -> a -> b) -> b -> Array sh a -> b
foldl a -> a -> a
forall a. Num a => a -> a -> a
(+) a
0

{- |
prop> \(Array16 xs)  ->  Array.product xs == product (Array.toList xs)
-}
product :: (Shape.C sh, Storable a, Num a) => Array sh a -> a
product :: Array sh a -> a
product = (a -> a -> a) -> a -> Array sh a -> a
forall sh a b.
(C sh, Storable a) =>
(b -> a -> b) -> b -> Array sh a -> b
foldl a -> a -> a
forall a. Num a => a -> a -> a
(*) a
1

{-# INLINE foldl #-}
foldl :: (Shape.C sh, Storable a) => (b -> a -> b) -> b -> Array sh a -> b
foldl :: (b -> a -> b) -> b -> Array sh a -> b
foldl b -> a -> b
op b
a (Array sh
sh ForeignPtr a
x) = IO b -> b
forall a. IO a -> a
unsafePerformIO (IO b -> b) -> IO b -> b
forall a b. (a -> b) -> a -> b
$
   ForeignPtr a -> (Ptr a -> IO b) -> IO b
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
x ((Ptr a -> IO b) -> IO b) -> (Ptr a -> IO b) -> IO b
forall a b. (a -> b) -> a -> b
$ \Ptr a
xPtr ->
      (Int -> b -> a -> b) -> b -> Int -> Ptr a -> Int -> IO b
forall a b.
Storable a =>
(Int -> b -> a -> b) -> b -> Int -> Ptr a -> Int -> IO b
Memory.foldl ((b -> a -> b) -> Int -> b -> a -> b
forall a b. a -> b -> a
const b -> a -> b
op) b
a (sh -> Int
forall sh. C sh => sh -> Int
Shape.size sh
sh) Ptr a
xPtr Int
1