module Data.Array.Comfort.Storable (
   Array,
   shape,
   reshape,
   mapShape,

   accessMaybe, (!),
   Array.toList,
   Array.vectorFromList,
   toAssociations,
   fromList,
   fromMap, toMap,
   fromTuple, toTuple,
   fromRecord, toRecord,
   fromContainer,
   toContainer,
   sample,
   fromBoxed,
   toBoxed,
   fromStorableVector,
   toStorableVector,

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

   pick,
   toRowArray,
   fromRowArray,
   Array.singleton,
   Array.append,
   Array.take, Array.drop,
   Array.takeLeft, Array.takeRight, Array.split,
   Array.takeCenter,

   Array.sum, Array.product,
   minimum, argMinimum,
   maximum, argMaximum,
   limits,
   Array.foldl,
   foldl1,
   foldMap,
   ) where

import qualified Data.Array.Comfort.Storable.Mutable.Unchecked as MutArrayNC
import qualified Data.Array.Comfort.Storable.Mutable as MutArray
import qualified Data.Array.Comfort.Storable.Unchecked as Array
import qualified Data.Array.Comfort.Storable.Memory as Memory
import qualified Data.Array.Comfort.Container as Container
import qualified Data.Array.Comfort.Boxed as BoxedArray
import qualified Data.Array.Comfort.Check as Check
import qualified Data.Array.Comfort.Shape.Tuple as TupleShape
import qualified Data.Array.Comfort.Shape as Shape
import Data.Array.Comfort.Storable.Unchecked (Array(Array))
import Data.Array.Comfort.Shape ((::+)((::+)))

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

import qualified Control.Monad.Trans.State as MS
import Control.Monad.ST (runST)

import qualified Data.StorableVector.Base as SVB
import qualified Data.Map as Map
import qualified Data.Set as Set
import qualified Data.Traversable as Trav
import qualified Data.Foldable as Fold
import qualified Data.List as List
import qualified Data.Tuple.Strict as StrictTuple
import Data.Map (Map)
import Data.Set (Set)
import Data.Foldable (forM_)
import Data.Maybe (fromMaybe)
import Data.Semigroup
         (Semigroup, (<>), Min(Min,getMin), Max(Max,getMax), Arg(Arg))

import Prelude2010 hiding (map, zipWith, foldl1, minimum, maximum)
import Prelude ()


{- $setup
>>> 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 Test.ChasingBottoms.IsBottom (isBottom)
>>>
>>> import Control.Applicative ((<$>), (<*>))
>>>
>>> import Data.Complex (Complex((:+)))
>>> import Data.Word (Word16)
>>>
>>> type ShapeInt = Shape.ZeroBased Int
>>>
>>> genArray :: QC.Gen (Array ShapeInt Word16)
>>> genArray = Array.vectorFromList <$> QC.arbitrary
>>>
>>> genArray2 :: QC.Gen (Array (ShapeInt,ShapeInt) Word16)
>>> genArray2 = do
>>>    xs <- QC.arbitrary
>>>    let n = length xs
>>>    (k,m) <-
>>>       if n == 0
>>>          then QC.elements [(,) 0, flip (,) 0] <*> QC.choose (1,n)
>>>          else fmap (\m -> (div n m, m)) $ QC.choose (1,n)
>>>    return $ Array.fromList (Shape.ZeroBased k, Shape.ZeroBased m) xs
>>>
>>> genNonEmptyArray2 :: QC.Gen (Array (ShapeInt,ShapeInt) Word16)
>>> genNonEmptyArray2 = do
>>>    xs <- QC.getNonEmpty <$> QC.arbitrary
>>>    let n = length xs
>>>    m <- QC.choose (1,n)
>>>    return $ Array.fromList (Shape.ZeroBased (div n m), Shape.ZeroBased m) xs
>>>
>>> infix 4 ==?
>>> (==?) :: a -> a -> (a,a)
>>> (==?) = (,)
>>>
>>> forAllNonEmpty :: (Eq b) => (Array ShapeInt Word16 -> (b,b)) -> QC.Property
>>> forAllNonEmpty f =
>>>    QC.forAll genArray $ \xs ->
>>>    case f xs of
>>>       (resultArray,resultList) ->
>>>          if Array.shape xs == Shape.ZeroBased 0
>>>             then isBottom resultArray
>>>             else resultArray == resultList
>>>
>>>
>>> type X = Shape.Element
-}


shape :: Array sh a -> sh
shape :: forall sh a. Array sh a -> sh
shape = forall sh a. Array sh a -> sh
Array.shape

reshape :: (Shape.C sh0, Shape.C sh1) => sh1 -> Array sh0 a -> Array sh1 a
reshape :: forall sh0 sh1 a.
(C sh0, C sh1) =>
sh1 -> Array sh0 a -> Array sh1 a
reshape = forall sh0 sh1 array0 array1.
(C sh0, C sh1) =>
String
-> (array0 -> sh0)
-> (sh1 -> array0 -> array1)
-> sh1
-> array0
-> array1
Check.reshape String
"Storable" forall sh a. Array sh a -> sh
shape forall sh1 sh0 a. sh1 -> Array sh0 a -> Array sh1 a
Array.reshape

mapShape ::
   (Shape.C sh0, Shape.C sh1) => (sh0 -> sh1) -> Array sh0 a -> Array sh1 a
mapShape :: forall sh0 sh1 a.
(C sh0, C sh1) =>
(sh0 -> sh1) -> Array sh0 a -> Array sh1 a
mapShape sh0 -> sh1
f Array sh0 a
arr = forall sh0 sh1 a.
(C sh0, C sh1) =>
sh1 -> Array sh0 a -> Array sh1 a
reshape (sh0 -> sh1
f forall a b. (a -> b) -> a -> b
$ forall sh a. Array sh a -> sh
shape Array sh0 a
arr) Array sh0 a
arr


{- |
>>> Array.fromList (Shape.ZeroBased (5::Int)) ['a'..]
StorableArray.fromList (ZeroBased {zeroBasedSize = 5}) "abcde"
-}
fromList :: (Shape.C sh, Storable a) => sh -> [a] -> Array sh a
fromList :: forall sh a. (C sh, Storable a) => sh -> [a] -> Array sh a
fromList sh
sh [a]
arr = forall a. (forall s. ST s a) -> a
runST (forall (m :: * -> *) sh a.
(PrimMonad m, C sh, Storable a) =>
Array m sh a -> m (Array sh a)
MutArrayNC.unsafeFreeze forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (m :: * -> *) sh a.
(PrimMonad m, C sh, Storable a) =>
sh -> [a] -> m (Array m sh a)
MutArray.fromList sh
sh [a]
arr)

fromMap :: (Ord k, Storable a) => Map k a -> Array (Set k) a
fromMap :: forall k a. (Ord k, Storable a) => Map k a -> Array (Set k) a
fromMap Map k a
m = forall sh a. (C sh, Storable a) => sh -> [a] -> Array sh a
fromList (forall k a. Map k a -> Set k
Map.keysSet Map k a
m) (forall k a. Map k a -> [a]
Map.elems Map k a
m)

toMap :: (Ord k, Storable a) => Array (Set k) a -> Map k a
toMap :: forall k a. (Ord k, Storable a) => Array (Set k) a -> Map k a
toMap Array (Set k) a
arr = forall k a. Eq k => [(k, a)] -> Map k a
Map.fromAscList forall a b. (a -> b) -> a -> b
$ forall a b. [a] -> [b] -> [(a, b)]
zip (forall a. Set a -> [a]
Set.toAscList forall a b. (a -> b) -> a -> b
$ forall sh a. Array sh a -> sh
shape Array (Set k) a
arr) (forall sh a. (C sh, Storable a) => Array sh a -> [a]
Array.toList Array (Set k) a
arr)

{- |
>>> Array.fromTuple ('a',('b','c')) :: Array.Array (Shape.NestedTuple Shape.TupleIndex (X,(X,X))) Char
StorableArray.fromList (NestedTuple {getNestedTuple = (Element 0,(Element 1,Element 2))}) "abc"

>>> :{ let arr = Array.fromTuple ('a',('b','c')) :: Array.Array (Shape.NestedTuple Shape.TupleAccessor (X,(X,X))) Char
in (arr ! fst, arr ! (fst.snd))
:}
('a','b')
-}
fromTuple ::
   (TupleShape.NestedTuple tuple, Storable a) =>
   Shape.DataTuple tuple a -> Array (Shape.NestedTuple ixtype tuple) a
fromTuple :: forall tuple a ixtype.
(NestedTuple tuple, Storable a) =>
DataTuple tuple a -> Array (NestedTuple ixtype tuple) a
fromTuple DataTuple tuple a
tuple =
   case forall s a. State s a -> s -> a
MS.evalState (forall shape a.
NestedTuple shape =>
DataTuple shape a -> State Element (shape, [a])
TupleShape.decons DataTuple tuple a
tuple) (Int -> Element
Shape.Element Int
0) of
      (tuple
sh, [a]
xs) -> forall sh a. (C sh, Storable a) => sh -> [a] -> Array sh a
fromList (forall ixtype tuple. tuple -> NestedTuple ixtype tuple
Shape.NestedTuple tuple
sh) [a]
xs

toTuple ::
   (TupleShape.NestedTuple tuple, Storable a) =>
   Array (Shape.NestedTuple ixtype tuple) a -> Shape.DataTuple tuple a
toTuple :: forall tuple a ixtype.
(NestedTuple tuple, Storable a) =>
Array (NestedTuple ixtype tuple) a -> DataTuple tuple a
toTuple Array (NestedTuple ixtype tuple) a
arr =
   forall s a. State s a -> s -> a
MS.evalState
      (forall shape a.
ElementTuple shape =>
shape -> State [a] (DataTuple shape a)
TupleShape.cons forall a b. (a -> b) -> a -> b
$ forall ixtype tuple. NestedTuple ixtype tuple -> tuple
Shape.getNestedTuple forall a b. (a -> b) -> a -> b
$ forall sh a. Array sh a -> sh
shape Array (NestedTuple ixtype tuple) a
arr)
      (forall sh a. (C sh, Storable a) => Array sh a -> [a]
Array.toList Array (NestedTuple ixtype tuple) a
arr)

{- |
>>> :{ let arr = Array.fromRecord ('a' :+ 'b') in
let (real:+imag) = Shape.indexRecordFromShape $ Array.shape arr in
(arr ! real, arr ! imag)
:}
('a','b')
-}
fromRecord ::
   (Trav.Traversable f, Storable a) =>
   f a -> Array (Shape.Record f) a
fromRecord :: forall (f :: * -> *) a.
(Traversable f, Storable a) =>
f a -> Array (Record f) a
fromRecord f a
xs =
   forall sh a. (C sh, Storable a) => sh -> [a] -> Array sh a
fromList
      (forall (f :: * -> *). f Element -> Record f
Shape.Record forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> b -> a -> c
flip forall s a. State s a -> s -> a
MS.evalState (Int -> Element
Shape.Element Int
0) forall a b. (a -> b) -> a -> b
$
       forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
Trav.traverse (forall a b. a -> b -> a
const State Element Element
TupleShape.next) f a
xs)
      (forall (t :: * -> *) a. Foldable t => t a -> [a]
Fold.toList f a
xs)

toRecord ::
   (Trav.Traversable f, Storable a) =>
   Array (Shape.Record f) a -> f a
toRecord :: forall (f :: * -> *) a.
(Traversable f, Storable a) =>
Array (Record f) a -> f a
toRecord Array (Record f) a
arr =
   forall s a. State s a -> s -> a
MS.evalState
      (forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
Trav.traverse (forall a b. a -> b -> a
const forall a. State [a] a
TupleShape.get) forall a b. (a -> b) -> a -> b
$
       (\(Shape.Record f Element
record) -> f Element
record) forall a b. (a -> b) -> a -> b
$ forall sh a. Array sh a -> sh
shape Array (Record f) a
arr)
      (forall sh a. (C sh, Storable a) => Array sh a -> [a]
Array.toList Array (Record f) a
arr)

fromContainer ::
   (Container.C f, Storable a) => f a -> Array (Container.Shape f) a
fromContainer :: forall (f :: * -> *) a.
(C f, Storable a) =>
f a -> Array (Shape f) a
fromContainer f a
xs = forall sh a. (C sh, Storable a) => sh -> [a] -> Array sh a
fromList (forall (f :: * -> *) a. C f => f a -> Shape f
Container.toShape f a
xs) (forall (t :: * -> *) a. Foldable t => t a -> [a]
Fold.toList f a
xs)

toContainer ::
   (Container.C f, Storable a) => Array (Container.Shape f) a -> f a
toContainer :: forall (f :: * -> *) a.
(C f, Storable a) =>
Array (Shape f) a -> f a
toContainer Array (Shape f) a
arr = forall (f :: * -> *) a. C f => Shape f -> [a] -> f a
Container.fromList (forall sh a. Array sh a -> sh
Array.shape Array (Shape f) a
arr) (forall sh a. (C sh, Storable a) => Array sh a -> [a]
Array.toList Array (Shape f) a
arr)

sample ::
   (Shape.Indexed sh, Storable a) => sh -> (Shape.Index sh -> a) -> Array sh a
sample :: forall sh a.
(Indexed sh, Storable a) =>
sh -> (Index sh -> a) -> Array sh a
sample sh
sh Index sh -> a
f = forall sh a. (C sh, Storable a) => sh -> [a] -> Array sh a
Array.fromList sh
sh forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
List.map Index sh -> a
f forall a b. (a -> b) -> a -> b
$ forall sh. Indexed sh => sh -> [Index sh]
Shape.indices sh
sh


fromBoxed :: (Shape.C sh, Storable a) => BoxedArray.Array sh a -> Array sh a
fromBoxed :: forall sh a. (C sh, Storable a) => Array sh a -> Array sh a
fromBoxed Array sh a
arr = forall sh a. (C sh, Storable a) => sh -> [a] -> Array sh a
Array.fromList (forall sh a. Array sh a -> sh
BoxedArray.shape Array sh a
arr) forall a b. (a -> b) -> a -> b
$ forall sh a. C sh => Array sh a -> [a]
BoxedArray.toList Array sh a
arr

toBoxed :: (Shape.C sh, Storable a) => Array sh a -> BoxedArray.Array sh a
toBoxed :: forall sh a. (C sh, Storable a) => Array sh a -> Array sh a
toBoxed Array sh a
arr = forall sh a. C sh => sh -> [a] -> Array sh a
BoxedArray.fromList (forall sh a. Array sh a -> sh
Array.shape Array sh a
arr) forall a b. (a -> b) -> a -> b
$ forall sh a. (C sh, Storable a) => Array sh a -> [a]
Array.toList Array sh a
arr


fromStorableVector ::
   (Storable a) => SVB.Vector a -> Array (Shape.ZeroBased Int) a
fromStorableVector :: forall a. Storable a => Vector a -> Array (ZeroBased Int) a
fromStorableVector Vector a
xs =
   case forall a. Vector a -> (ForeignPtr a, Int, Int)
SVB.toForeignPtr Vector a
xs of
      (ForeignPtr a
fptr,Int
0,Int
n) -> forall sh a. sh -> ForeignPtr a -> Array sh a
Array (forall n. n -> ZeroBased n
Shape.ZeroBased Int
n) ForeignPtr a
fptr
      (ForeignPtr a
fptr,Int
s,Int
n) ->
         forall sh0 sh1 a.
(C sh0, C sh1, Storable a) =>
Array (sh0 ::+ sh1) a -> Array sh1 a
Array.takeRight forall a b. (a -> b) -> a -> b
$
         forall sh a. sh -> ForeignPtr a -> Array sh a
Array (forall n. n -> ZeroBased n
Shape.ZeroBased Int
s forall sh0 sh1. sh0 -> sh1 -> sh0 ::+ sh1
::+ forall n. n -> ZeroBased n
Shape.ZeroBased Int
n) ForeignPtr a
fptr

toStorableVector :: (Shape.C sh, Storable a) => Array sh a -> SVB.Vector a
toStorableVector :: forall sh a. (C sh, Storable a) => Array sh a -> Vector a
toStorableVector (Array sh
sh ForeignPtr a
fptr) =
   forall a. ForeignPtr a -> Int -> Vector a
SVB.fromForeignPtr ForeignPtr a
fptr forall a b. (a -> b) -> a -> b
$ forall sh. C sh => sh -> Int
Shape.size sh
sh


toAssociations ::
   (Shape.Indexed sh, Storable a) => Array sh a -> [(Shape.Index sh, a)]
toAssociations :: forall sh a.
(Indexed sh, Storable a) =>
Array sh a -> [(Index sh, a)]
toAssociations Array sh a
arr = forall a b. [a] -> [b] -> [(a, b)]
zip (forall sh. Indexed sh => sh -> [Index sh]
Shape.indices forall a b. (a -> b) -> a -> b
$ forall sh a. Array sh a -> sh
shape Array sh a
arr) (forall sh a. (C sh, Storable a) => Array sh a -> [a]
Array.toList Array sh a
arr)


errorArray :: String -> String -> a
errorArray :: forall a. String -> String -> a
errorArray String
name String
msg =
   forall a. HasCallStack => String -> a
error (String
"Array.Comfort.Storable." forall a. [a] -> [a] -> [a]
++ String
name forall a. [a] -> [a] -> [a]
++ String
": " forall a. [a] -> [a] -> [a]
++ String
msg)

infixl 9 !

(!) :: (Shape.Indexed sh, Storable a) => Array sh a -> Shape.Index sh -> a
! :: forall sh a.
(Indexed sh, Storable a) =>
Array sh a -> Index sh -> a
(!) Array sh a
arr Index sh
ix =
   forall a. a -> Maybe a -> a
fromMaybe (forall a. String -> String -> a
errorArray String
"!" String
"index out of bounds") forall a b. (a -> b) -> a -> b
$
   forall sh a.
(Indexed sh, Storable a) =>
Array sh a -> Index sh -> Maybe a
accessMaybe Array sh a
arr Index sh
ix

accessMaybe ::
   (Shape.Indexed sh, Storable a) => Array sh a -> Shape.Index sh -> Maybe a
accessMaybe :: forall sh a.
(Indexed sh, Storable a) =>
Array sh a -> Index sh -> Maybe a
accessMaybe Array sh a
arr Index sh
ix = forall a. (forall s. ST s a) -> a
runST (do
   Array (ST s) sh a
marr <- forall (m :: * -> *) sh a.
(PrimMonad m, C sh, Storable a) =>
Array sh a -> m (Array m sh a)
MutArrayNC.unsafeThaw Array sh a
arr
   forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
Trav.sequenceA forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) sh a.
(PrimMonad m, Indexed sh, Storable a) =>
Array m sh a -> Index sh -> Maybe (m a)
MutArray.readMaybe Array (ST s) sh a
marr Index sh
ix)


zipWith ::
   (Shape.C sh, Eq sh, Storable a, Storable b, Storable c) =>
   (a -> b -> c) -> Array sh a -> Array sh b -> Array sh c
zipWith :: forall sh a b c.
(C sh, Eq sh, Storable a, Storable b, Storable c) =>
(a -> b -> c) -> Array sh a -> Array sh b -> Array sh c
zipWith a -> b -> c
f Array sh a
a Array sh b
b =
   if forall sh a. Array sh a -> sh
shape Array sh a
a forall a. Eq a => a -> a -> Bool
== forall sh a. Array sh a -> sh
shape Array sh b
b
      then forall sh a b c.
(C sh, Storable a, Storable b, Storable c) =>
(a -> b -> c) -> Array sh a -> Array sh b -> Array sh c
Array.zipWith a -> b -> c
f Array sh a
a Array sh b
b
      else forall a. String -> String -> a
errorArray String
"zipWith" String
"shapes mismatch"

(//) ::
   (Shape.Indexed sh, Storable a) =>
   Array sh a -> [(Shape.Index sh, a)] -> Array sh a
// :: forall sh a.
(Indexed sh, Storable a) =>
Array sh a -> [(Index sh, a)] -> Array sh a
(//) Array sh a
arr [(Index sh, a)]
xs = forall a. (forall s. ST s a) -> a
runST (do
   Array (ST s) sh a
marr <- forall (m :: * -> *) sh a.
(PrimMonad m, C sh, Storable a) =>
Array sh a -> m (Array m sh a)
MutArray.thaw Array sh a
arr
   forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [(Index sh, a)]
xs forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) sh a.
(PrimMonad m, Indexed sh, Storable a) =>
Array m sh a -> Index sh -> a -> m ()
MutArray.write Array (ST s) sh a
marr
   forall (m :: * -> *) sh a.
(PrimMonad m, C sh, Storable a) =>
Array m sh a -> m (Array sh a)
MutArrayNC.unsafeFreeze Array (ST s) sh a
marr)

accumulate ::
   (Shape.Indexed sh, Storable a) =>
   (a -> b -> a) -> Array sh a -> [(Shape.Index sh, b)] -> Array sh a
accumulate :: forall sh a b.
(Indexed sh, Storable a) =>
(a -> b -> a) -> Array sh a -> [(Index sh, b)] -> Array sh a
accumulate a -> b -> a
f Array sh a
arr [(Index sh, b)]
xs = forall a. (forall s. ST s a) -> a
runST (do
   Array (ST s) sh a
marr <- forall (m :: * -> *) sh a.
(PrimMonad m, C sh, Storable a) =>
Array sh a -> m (Array m sh a)
MutArray.thaw Array sh a
arr
   forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [(Index sh, b)]
xs forall a b. (a -> b) -> a -> b
$ \(Index sh
ix,b
b) -> forall (m :: * -> *) sh a.
(PrimMonad m, Indexed sh, Storable a) =>
Array m sh a -> Index sh -> (a -> a) -> m ()
MutArray.update Array (ST s) sh a
marr Index sh
ix forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> b -> a
f b
b
   forall (m :: * -> *) sh a.
(PrimMonad m, C sh, Storable a) =>
Array m sh a -> m (Array sh a)
MutArrayNC.unsafeFreeze Array (ST s) sh a
marr)

fromAssociations ::
   (Shape.Indexed sh, Storable a) =>
   a -> sh -> [(Shape.Index sh, a)] -> Array sh a
fromAssociations :: forall sh a.
(Indexed sh, Storable a) =>
a -> sh -> [(Index sh, a)] -> Array sh a
fromAssociations a
a sh
sh [(Index sh, a)]
xs = forall a. (forall s. ST s a) -> a
runST (do
   Array (ST s) sh a
marr <- forall (m :: * -> *) sh a.
(PrimMonad m, C sh, Storable a) =>
sh -> a -> m (Array m sh a)
MutArray.new sh
sh a
a
   forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [(Index sh, a)]
xs forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) sh a.
(PrimMonad m, Indexed sh, Storable a) =>
Array m sh a -> Index sh -> a -> m ()
MutArray.write Array (ST s) sh a
marr
   forall (m :: * -> *) sh a.
(PrimMonad m, C sh, Storable a) =>
Array m sh a -> m (Array sh a)
MutArrayNC.unsafeFreeze Array (ST s) sh a
marr)


{- |
prop> QC.forAll genNonEmptyArray2 $ \xs -> QC.forAll (QC.elements $ Shape.indices $ Array.shape xs) $ \(ix0,ix1) -> Array.pick xs ix0 ! ix1 == xs!(ix0,ix1)
-}
pick ::
   (Shape.Indexed sh0, Shape.C sh1, Storable a) =>
   Array (sh0,sh1) a -> Shape.Index sh0 -> Array sh1 a
pick :: forall sh0 sh1 a.
(Indexed sh0, C sh1, Storable a) =>
Array (sh0, sh1) a -> Index sh0 -> Array sh1 a
pick (Array (sh0
sh0,sh1
sh1) ForeignPtr a
x) Index sh0
ix0 =
   forall sh a.
(C sh, Storable a) =>
sh -> (Int -> Ptr a -> IO ()) -> Array sh a
Array.unsafeCreateWithSize sh1
sh1 forall a b. (a -> b) -> a -> b
$ \Int
k Ptr a
yPtr ->
   forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
x forall a b. (a -> b) -> a -> b
$ \Ptr a
xPtr ->
      forall a. Storable a => Ptr a -> Ptr a -> Int -> IO ()
copyArray Ptr a
yPtr (forall a. Storable a => Ptr a -> Int -> Ptr a
advancePtr Ptr a
xPtr (forall sh. Indexed sh => sh -> Index sh -> Int
Shape.offset sh0
sh0 Index sh0
ix0 forall a. Num a => a -> a -> a
* Int
k)) Int
k

toRowArray ::
   (Shape.Indexed sh0, Shape.C sh1, Storable a) =>
   Array (sh0,sh1) a -> BoxedArray.Array sh0 (Array sh1 a)
toRowArray :: forall sh0 sh1 a.
(Indexed sh0, C sh1, Storable a) =>
Array (sh0, sh1) a -> Array sh0 (Array sh1 a)
toRowArray Array (sh0, sh1) a
x = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall sh0 sh1 a.
(Indexed sh0, C sh1, Storable a) =>
Array (sh0, sh1) a -> Index sh0 -> Array sh1 a
pick Array (sh0, sh1) a
x) forall a b. (a -> b) -> a -> b
$ forall sh. Indexed sh => sh -> Array sh (Index sh)
BoxedArray.indices forall a b. (a -> b) -> a -> b
$ forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$ forall sh a. Array sh a -> sh
Array.shape Array (sh0, sh1) a
x

{- |
It is a checked error if a row width differs from the result array width.

prop> QC.forAll genArray2 $ \xs -> xs == Array.fromRowArray (snd $ Array.shape xs) (Array.toRowArray xs)
-}
fromRowArray ::
   (Shape.C sh0, Shape.C sh1, Eq sh1, Storable a) =>
   sh1 -> BoxedArray.Array sh0 (Array sh1 a) -> Array (sh0,sh1) a
fromRowArray :: forall sh0 sh1 a.
(C sh0, C sh1, Eq sh1, Storable a) =>
sh1 -> Array sh0 (Array sh1 a) -> Array (sh0, sh1) a
fromRowArray sh1
sh1 Array sh0 (Array sh1 a)
x =
   forall sh a.
(C sh, Storable a) =>
sh -> (Ptr a -> IO ()) -> Array sh a
Array.unsafeCreate (forall sh a. Array sh a -> sh
BoxedArray.shape Array sh0 (Array sh1 a)
x, sh1
sh1) forall a b. (a -> b) -> a -> b
$ \Ptr a
yPtr ->
   let k :: Int
k = forall sh. C sh => sh -> Int
Shape.size sh1
sh1 in
   forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0,Int
k..] (forall sh a. C sh => Array sh a -> [a]
BoxedArray.toList Array sh0 (Array sh1 a)
x)) forall a b. (a -> b) -> a -> b
$ \(Int
j, Array sh1
sh1i ForeignPtr a
row) ->
   if sh1
sh1 forall a. Eq a => a -> a -> Bool
== sh1
sh1i
      then forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
row forall a b. (a -> b) -> a -> b
$ \Ptr a
xPtr -> forall a. Storable a => Ptr a -> Ptr a -> Int -> IO ()
copyArray (forall a. Storable a => Ptr a -> Int -> Ptr a
advancePtr Ptr a
yPtr Int
j) Ptr a
xPtr Int
k
      else forall a. String -> String -> a
errorArray String
"fromRowArray" String
"mismatching row width"


{- |
It is a checked error if the vector is empty.

prop> forAllNonEmpty $ \xs -> Array.minimum xs ==? minimum (Array.toList xs)
-}
minimum :: (Shape.C sh, Storable a, Ord a) => Array sh a -> a
minimum :: forall sh a. (C sh, Storable a, Ord a) => Array sh a -> a
minimum = forall sh a. (C sh, Storable a) => (a -> a -> a) -> Array sh a -> a
foldl1 forall a. Ord a => a -> a -> a
min

{- |
It is a checked error if the vector is empty.

prop> forAllNonEmpty $ \xs -> Array.maximum xs ==? maximum (Array.toList xs)
-}
maximum :: (Shape.C sh, Storable a, Ord a) => Array sh a -> a
maximum :: forall sh a. (C sh, Storable a, Ord a) => Array sh a -> a
maximum = forall sh a. (C sh, Storable a) => (a -> a -> a) -> Array sh a -> a
foldl1 forall a. Ord a => a -> a -> a
max

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

{- |
prop> forAllNonEmpty $ \xs -> Array.limits xs ==? (Array.minimum xs, Array.maximum xs)
-}
limits :: (Shape.C sh, Storable a, Ord a) => Array sh a -> (a,a)
limits :: forall sh a. (C sh, Storable a, Ord a) => Array sh a -> (a, a)
limits = forall a c b d. (a -> c, b -> d) -> (a, b) -> (c, d)
StrictTuple.mapPair (forall a. Min a -> a
getMin, forall a. Max a -> a
getMax) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall sh a m.
(C sh, Storable a, Ord a, Semigroup m) =>
(a -> m) -> Array sh a -> m
foldMap (\a
x -> (forall a. a -> Min a
Min a
x, forall a. a -> Max a
Max a
x))

{-# INLINE foldMap #-}
foldMap ::
   (Shape.C sh, Storable a, Ord a, Semigroup m) => (a -> m) -> Array sh a -> m
foldMap :: forall sh a m.
(C sh, Storable a, Ord a, Semigroup m) =>
(a -> m) -> Array sh a -> m
foldMap a -> m
f (Array sh
sh ForeignPtr a
x) = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
   forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
x forall a b. (a -> b) -> a -> b
$ \Ptr a
xPtr ->
      forall a b.
Storable a =>
(Int -> a -> b) -> (b -> b -> b) -> Int -> Ptr a -> Int -> IO b
Memory.foldl1 (forall a b. a -> b -> a
const a -> m
f) forall a. Semigroup a => a -> a -> a
(<>) (forall sh. C sh => sh -> Int
Shape.size sh
sh) Ptr a
xPtr Int
1


argMinimum, argMaximum ::
   (Shape.InvIndexed sh, Storable a, Ord a) =>
   Array sh a -> (Shape.Index sh, a)
argMinimum :: forall sh a.
(InvIndexed sh, Storable a, Ord a) =>
Array sh a -> (Index sh, a)
argMinimum Array sh a
xs = forall sh a.
InvIndexed sh =>
Array sh a -> Arg a Int -> (Index sh, a)
unArg Array sh a
xs forall a b. (a -> b) -> a -> b
$ forall a. Min a -> a
getMin forall a b. (a -> b) -> a -> b
$ forall sh a m.
(C sh, Storable a, Semigroup m) =>
(Int -> a -> m) -> Array sh a -> m
foldMapWithIndex (\Int
k a
x -> forall a. a -> Min a
Min (forall a b. a -> b -> Arg a b
Arg a
x Int
k)) Array sh a
xs
argMaximum :: forall sh a.
(InvIndexed sh, Storable a, Ord a) =>
Array sh a -> (Index sh, a)
argMaximum Array sh a
xs = forall sh a.
InvIndexed sh =>
Array sh a -> Arg a Int -> (Index sh, a)
unArg Array sh a
xs forall a b. (a -> b) -> a -> b
$ forall a. Max a -> a
getMax forall a b. (a -> b) -> a -> b
$ forall sh a m.
(C sh, Storable a, Semigroup m) =>
(Int -> a -> m) -> Array sh a -> m
foldMapWithIndex (\Int
k a
x -> forall a. a -> Max a
Max (forall a b. a -> b -> Arg a b
Arg a
x Int
k)) Array sh a
xs

unArg ::
   (Shape.InvIndexed sh) => Array sh a -> Arg a Int -> (Shape.Index sh, a)
unArg :: forall sh a.
InvIndexed sh =>
Array sh a -> Arg a Int -> (Index sh, a)
unArg Array sh a
xs (Arg a
x Int
k) = (forall sh. InvIndexed sh => sh -> Int -> Index sh
Shape.indexFromOffset (forall sh a. Array sh a -> sh
Array.shape Array sh a
xs) Int
k, a
x)

{-# INLINE foldMapWithIndex #-}
foldMapWithIndex ::
   (Shape.C sh, Storable a, Semigroup m) => (Int -> a -> m) -> Array sh a -> m
foldMapWithIndex :: forall sh a m.
(C sh, Storable a, Semigroup m) =>
(Int -> a -> m) -> Array sh a -> m
foldMapWithIndex Int -> a -> m
f (Array sh
sh ForeignPtr a
x) = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
   forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
x forall a b. (a -> b) -> a -> b
$ \Ptr a
xPtr -> forall a b.
Storable a =>
(Int -> a -> b) -> (b -> b -> b) -> Int -> Ptr a -> Int -> IO b
Memory.foldl1 Int -> a -> m
f forall a. Semigroup a => a -> a -> a
(<>) (forall sh. C sh => sh -> Int
Shape.size sh
sh) Ptr a
xPtr Int
1