{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
module Data.Massiv.Array.Ops.Slice (
(!>),
(!?>),
(??>),
(<!),
(<!?),
(<??),
(<!>),
(<!?>),
(<??>),
outerSlices,
innerSlices,
withinSlices,
withinSlicesM,
) where
import Control.Monad (unless)
import Data.Massiv.Array.Delayed.Pull
import Data.Massiv.Core.Common
infixl 4 !>, !?>, ??>, <!, <!?, <??, <!>, <!?>, <??>
(!>)
:: forall r ix e
. (HasCallStack, Index ix, Index (Lower ix), Source r e)
=> Array r ix e
-> Int
-> Array r (Lower ix) e
!> :: forall r ix e.
(HasCallStack, Index ix, Index (Lower ix), Source r e) =>
Array r ix e -> Int -> Array r (Lower ix) e
(!>) !Array r ix e
arr !Int
ix = forall a. HasCallStack => Either SomeException a -> a
throwEither (Array r ix e
arr forall r ix e (m :: * -> *).
(MonadThrow m, Index ix, Index (Lower ix), Source r e) =>
Array r ix e -> Int -> m (Array r (Lower ix) e)
!?> Int
ix)
{-# INLINE (!>) #-}
(!?>)
:: forall r ix e m
. (MonadThrow m, Index ix, Index (Lower ix), Source r e)
=> Array r ix e
-> Int
-> m (Array r (Lower ix) e)
!?> :: forall r ix e (m :: * -> *).
(MonadThrow m, Index ix, Index (Lower ix), Source r e) =>
Array r ix e -> Int -> m (Array r (Lower ix) e)
(!?>) !Array r ix e
arr !Int
i = do
let (Sz Int
k, Sz (Lower ix)
szL) = forall ix. Index ix => Sz ix -> (Sz Int, Sz (Lower ix))
unconsSz (forall r ix e. Size r => Array r ix e -> Sz ix
size Array r ix e
arr)
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (forall ix. Index ix => Sz ix -> ix -> Bool
isSafeIndex Sz Int
k Int
i) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ forall ix. Index ix => Sz ix -> ix -> IndexException
IndexOutOfBoundsException Sz Int
k Int
i
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall r e ix.
(Source r e, Index ix, Index (Lower ix)) =>
Array r ix e -> Sz (Lower ix) -> Int -> Array r (Lower ix) e
unsafeOuterSlice Array r ix e
arr Sz (Lower ix)
szL Int
i
{-# INLINE (!?>) #-}
(??>)
:: forall r ix e m
. (MonadThrow m, Index ix, Index (Lower ix), Source r e)
=> m (Array r ix e)
-> Int
-> m (Array r (Lower ix) e)
??> :: forall r ix e (m :: * -> *).
(MonadThrow m, Index ix, Index (Lower ix), Source r e) =>
m (Array r ix e) -> Int -> m (Array r (Lower ix) e)
(??>) m (Array r ix e)
marr !Int
ix = m (Array r ix e)
marr forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (forall r ix e (m :: * -> *).
(MonadThrow m, Index ix, Index (Lower ix), Source r e) =>
Array r ix e -> Int -> m (Array r (Lower ix) e)
!?> Int
ix)
{-# INLINE (??>) #-}
(<!?)
:: forall r ix e m
. (MonadThrow m, Index ix, Source r e)
=> Array r ix e
-> Int
-> m (Array D (Lower ix) e)
<!? :: forall r ix e (m :: * -> *).
(MonadThrow m, Index ix, Source r e) =>
Array r ix e -> Int -> m (Array D (Lower ix) e)
(<!?) !Array r ix e
arr !Int
i = do
let (Sz (Lower ix)
szL, Sz Int
m) = forall ix. Index ix => Sz ix -> (Sz (Lower ix), Sz Int)
unsnocSz (forall r ix e. Size r => Array r ix e -> Sz ix
size Array r ix e
arr)
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (forall ix. Index ix => Sz ix -> ix -> Bool
isSafeIndex Sz Int
m Int
i) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ forall ix. Index ix => Sz ix -> ix -> IndexException
IndexOutOfBoundsException Sz Int
m Int
i
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall r e ix.
(Source r e, Index ix) =>
Array r ix e -> Sz (Lower ix) -> Int -> Array D (Lower ix) e
unsafeInnerSlice Array r ix e
arr Sz (Lower ix)
szL Int
i
{-# INLINE (<!?) #-}
(<!)
:: forall r ix e
. (HasCallStack, Index ix, Source r e)
=> Array r ix e
-> Int
-> Array D (Lower ix) e
<! :: forall r ix e.
(HasCallStack, Index ix, Source r e) =>
Array r ix e -> Int -> Array D (Lower ix) e
(<!) !Array r ix e
arr !Int
ix = forall a. HasCallStack => Either SomeException a -> a
throwEither (Array r ix e
arr forall r ix e (m :: * -> *).
(MonadThrow m, Index ix, Source r e) =>
Array r ix e -> Int -> m (Array D (Lower ix) e)
<!? Int
ix)
{-# INLINE (<!) #-}
(<??)
:: forall r ix e m
. (MonadThrow m, Index ix, Source r e)
=> m (Array r ix e)
-> Int
-> m (Array D (Lower ix) e)
<?? :: forall r ix e (m :: * -> *).
(MonadThrow m, Index ix, Source r e) =>
m (Array r ix e) -> Int -> m (Array D (Lower ix) e)
(<??) m (Array r ix e)
marr !Int
ix = m (Array r ix e)
marr forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (forall r ix e (m :: * -> *).
(MonadThrow m, Index ix, Source r e) =>
Array r ix e -> Int -> m (Array D (Lower ix) e)
<!? Int
ix)
{-# INLINE (<??) #-}
(<!?>)
:: forall r ix e m
. (MonadThrow m, Index ix, Index (Lower ix), Source r e)
=> Array r ix e
-> (Dim, Int)
-> m (Array D (Lower ix) e)
<!?> :: forall r ix e (m :: * -> *).
(MonadThrow m, Index ix, Index (Lower ix), Source r e) =>
Array r ix e -> (Dim, Int) -> m (Array D (Lower ix) e)
(<!?>) !Array r ix e
arr (Dim
dim, Int
i) = do
(Sz Int
m, Sz (Lower ix)
szl) <- forall (m :: * -> *) ix.
(MonadThrow m, Index ix) =>
Sz ix -> Dim -> m (Sz Int, Sz (Lower ix))
pullOutSzM (forall r ix e. Size r => Array r ix e -> Sz ix
size Array r ix e
arr) Dim
dim
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (forall ix. Index ix => Sz ix -> ix -> Bool
isSafeIndex Sz Int
m Int
i) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ forall ix. Index ix => Sz ix -> ix -> IndexException
IndexOutOfBoundsException Sz Int
m Int
i
Sz ix
cutSz <- forall (m :: * -> *) ix.
(MonadThrow m, Index ix) =>
Sz (Lower ix) -> Dim -> Sz Int -> m (Sz ix)
insertSzM Sz (Lower ix)
szl Dim
dim forall ix. Index ix => Sz ix
oneSz
forall (m :: * -> *) ix r e.
(MonadThrow m, Index ix, Index (Lower ix), Source r e) =>
Dim -> Sz ix -> Array r ix e -> Int -> m (Array D (Lower ix) e)
internalInnerSlice Dim
dim Sz ix
cutSz Array r ix e
arr Int
i
{-# INLINE (<!?>) #-}
internalInnerSlice
:: (MonadThrow m, Index ix, Index (Lower ix), Source r e)
=> Dim
-> Sz ix
-> Array r ix e
-> Ix1
-> m (Array D (Lower ix) e)
internalInnerSlice :: forall (m :: * -> *) ix r e.
(MonadThrow m, Index ix, Index (Lower ix), Source r e) =>
Dim -> Sz ix -> Array r ix e -> Int -> m (Array D (Lower ix) e)
internalInnerSlice Dim
dim Sz ix
cutSz Array r ix e
arr Int
i = do
ix
start <- forall ix (m :: * -> *).
(Index ix, MonadThrow m) =>
ix -> Dim -> Int -> m ix
setDimM forall ix. Index ix => ix
zeroIndex Dim
dim Int
i
forall r e ix (m :: * -> *).
(Source r e, Index ix, Index (Lower ix), MonadThrow m) =>
Array r ix e -> ix -> Sz ix -> Dim -> m (Array D (Lower ix) e)
unsafeSlice Array r ix e
arr ix
start Sz ix
cutSz Dim
dim
{-# INLINE internalInnerSlice #-}
(<!>)
:: forall r ix e
. (HasCallStack, Index ix, Index (Lower ix), Source r e)
=> Array r ix e
-> (Dim, Int)
-> Array D (Lower ix) e
<!> :: forall r ix e.
(HasCallStack, Index ix, Index (Lower ix), Source r e) =>
Array r ix e -> (Dim, Int) -> Array D (Lower ix) e
(<!>) !Array r ix e
arr !(Dim, Int)
dix = forall a. HasCallStack => Either SomeException a -> a
throwEither (Array r ix e
arr forall r ix e (m :: * -> *).
(MonadThrow m, Index ix, Index (Lower ix), Source r e) =>
Array r ix e -> (Dim, Int) -> m (Array D (Lower ix) e)
<!?> (Dim, Int)
dix)
{-# INLINE (<!>) #-}
(<??>)
:: forall r ix e m
. (MonadThrow m, Index ix, Index (Lower ix), Source r e)
=> m (Array r ix e)
-> (Dim, Int)
-> m (Array D (Lower ix) e)
<??> :: forall r ix e (m :: * -> *).
(MonadThrow m, Index ix, Index (Lower ix), Source r e) =>
m (Array r ix e) -> (Dim, Int) -> m (Array D (Lower ix) e)
(<??>) !m (Array r ix e)
marr !(Dim, Int)
ix = m (Array r ix e)
marr forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (forall r ix e (m :: * -> *).
(MonadThrow m, Index ix, Index (Lower ix), Source r e) =>
Array r ix e -> (Dim, Int) -> m (Array D (Lower ix) e)
<!?> (Dim, Int)
ix)
{-# INLINE (<??>) #-}
outerSlices
:: forall r ix e
. (Index ix, Index (Lower ix), Source r e)
=> Array r ix e
-> Array D Ix1 (Array r (Lower ix) e)
outerSlices :: forall r ix e.
(Index ix, Index (Lower ix), Source r e) =>
Array r ix e -> Array D Int (Array r (Lower ix) e)
outerSlices Array r ix e
arr = forall r ix e.
Load r ix e =>
Comp -> Sz ix -> (ix -> e) -> Array r ix e
makeArray (forall r ix e. Strategy r => Array r ix e -> Comp
getComp Array r ix e
arr) Sz Int
k (forall r e ix.
(Source r e, Index ix, Index (Lower ix)) =>
Array r ix e -> Sz (Lower ix) -> Int -> Array r (Lower ix) e
unsafeOuterSlice (forall r ix e. Strategy r => Comp -> Array r ix e -> Array r ix e
setComp Comp
Seq Array r ix e
arr) Sz (Lower ix)
szL)
where
(Sz Int
k, Sz (Lower ix)
szL) = forall ix. Index ix => Sz ix -> (Sz Int, Sz (Lower ix))
unconsSz forall a b. (a -> b) -> a -> b
$ forall r ix e. Size r => Array r ix e -> Sz ix
size Array r ix e
arr
{-# INLINE outerSlices #-}
innerSlices
:: forall r ix e
. (Index ix, Source r e)
=> Array r ix e
-> Array D Ix1 (Array D (Lower ix) e)
innerSlices :: forall r ix e.
(Index ix, Source r e) =>
Array r ix e -> Array D Int (Array D (Lower ix) e)
innerSlices Array r ix e
arr = forall r ix e.
Load r ix e =>
Comp -> Sz ix -> (ix -> e) -> Array r ix e
makeArray (forall r ix e. Strategy r => Array r ix e -> Comp
getComp Array r ix e
arr) Sz Int
k (forall r e ix.
(Source r e, Index ix) =>
Array r ix e -> Sz (Lower ix) -> Int -> Array D (Lower ix) e
unsafeInnerSlice (forall r ix e. Strategy r => Comp -> Array r ix e -> Array r ix e
setComp Comp
Seq Array r ix e
arr) Sz (Lower ix)
szL)
where
(Sz (Lower ix)
szL, Sz Int
k) = forall ix. Index ix => Sz ix -> (Sz (Lower ix), Sz Int)
unsnocSz forall a b. (a -> b) -> a -> b
$ forall r ix e. Size r => Array r ix e -> Sz ix
size Array r ix e
arr
{-# INLINE innerSlices #-}
withinSlices
:: forall n r ix e
. (IsIndexDimension ix n, Index (Lower ix), Source r e)
=> Dimension n
-> Array r ix e
-> Array D Ix1 (Array D (Lower ix) e)
withinSlices :: forall (n :: Natural) r ix e.
(IsIndexDimension ix n, Index (Lower ix), Source r e) =>
Dimension n -> Array r ix e -> Array D Int (Array D (Lower ix) e)
withinSlices Dimension n
dim = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall e a. (HasCallStack, Exception e) => e -> a
throwImpossible forall a. a -> a
id forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r ix e (m :: * -> *).
(MonadThrow m, Index ix, Index (Lower ix), Source r e) =>
Dim -> Array r ix e -> m (Array D Int (Array D (Lower ix) e))
withinSlicesM (forall (n :: Natural). KnownNat n => Dimension n -> Dim
fromDimension Dimension n
dim)
{-# INLINE withinSlices #-}
withinSlicesM
:: forall r ix e m
. (MonadThrow m, Index ix, Index (Lower ix), Source r e)
=> Dim
-> Array r ix e
-> m (Array D Ix1 (Array D (Lower ix) e))
withinSlicesM :: forall r ix e (m :: * -> *).
(MonadThrow m, Index ix, Index (Lower ix), Source r e) =>
Dim -> Array r ix e -> m (Array D Int (Array D (Lower ix) e))
withinSlicesM Dim
dim Array r ix e
arr = do
(Sz Int
k, Sz (Lower ix)
szl) <- forall (m :: * -> *) ix.
(MonadThrow m, Index ix) =>
Sz ix -> Dim -> m (Sz Int, Sz (Lower ix))
pullOutSzM (forall r ix e. Size r => Array r ix e -> Sz ix
size Array r ix e
arr) Dim
dim
Sz ix
cutSz <- forall (m :: * -> *) ix.
(MonadThrow m, Index ix) =>
Sz (Lower ix) -> Dim -> Sz Int -> m (Sz ix)
insertSzM Sz (Lower ix)
szl Dim
dim forall ix. Index ix => Sz ix
oneSz
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall r ix e.
Load r ix e =>
Comp -> Sz ix -> (ix -> e) -> Array r ix e
makeArray Comp
Seq Sz Int
k (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall e a. (HasCallStack, Exception e) => e -> a
throwImpossible forall a. a -> a
id forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) ix r e.
(MonadThrow m, Index ix, Index (Lower ix), Source r e) =>
Dim -> Sz ix -> Array r ix e -> Int -> m (Array D (Lower ix) e)
internalInnerSlice Dim
dim Sz ix
cutSz Array r ix e
arr)
{-# INLINE withinSlicesM #-}