Copyright | (c) Alexey Kuleshevich 2018 |
---|---|

License | BSD3 |

Maintainer | Alexey Kuleshevich <lehins@yandex.ru> |

Stability | experimental |

Portability | non-portable |

Safe Haskell | None |

Language | Haskell2010 |

## Synopsis

- type Ix1 = Int
- pattern Ix1 :: Int -> Ix1
- data Ix2 = (:.) !Int !Int
- pattern Ix2 :: Int -> Int -> Ix2
- type Ix3 = IxN 3
- pattern Ix3 :: Int -> Int -> Int -> Ix3
- type Ix4 = IxN 4
- pattern Ix4 :: Int -> Int -> Int -> Int -> Ix4
- type Ix5 = IxN 5
- pattern Ix5 :: Int -> Int -> Int -> Int -> Int -> Ix5
- data IxN (n :: Nat) = (:>) !Int !(Ix (n - 1))
- type family Ix (n :: Nat) = r | r -> n where ...
- toIx2 :: Ix2T -> Ix2
- fromIx2 :: Ix2 -> Ix2T
- toIx3 :: Ix3T -> Ix3
- fromIx3 :: Ix3 -> Ix3T
- toIx4 :: Ix4T -> Ix4
- fromIx4 :: Ix4 -> Ix4T
- toIx5 :: Ix5T -> Ix5
- fromIx5 :: Ix5 -> Ix5T
- data Stride ix
- pattern Stride :: Index ix => ix -> Stride ix
- unStride :: Stride ix -> ix
- toLinearIndexStride :: Index ix => Stride ix -> ix -> ix -> Int
- strideStart :: Index ix => Stride ix -> ix -> ix
- strideSize :: Index ix => Stride ix -> Sz ix -> ix
- oneStride :: Index ix => Stride ix
- data Border e
- handleBorderIndex :: Index ix => Border e -> Sz ix -> (ix -> e) -> ix -> e
- type Sz ix = ix
- pattern Sz :: ix -> Sz ix
- type Sz1 = Sz Int
- pattern Sz1 :: Int -> Int
- newtype Dim = Dim Int
- data Dimension (n :: Nat) where
- type IsIndexDimension ix n = (1 <= n, n <= Dimensions ix, Index ix, KnownNat n)
- data Ix0 = Ix0
- type Ix1T = Int
- type Ix2T = (Int, Int)
- type Ix3T = (Int, Int, Int)
- type Ix4T = (Int, Int, Int, Int)
- type Ix5T = (Int, Int, Int, Int, Int)
- type family Lower ix :: *
- class (Eq ix, Ord ix, Show ix, NFData ix) => Index ix where
- type Dimensions ix :: Nat
- dimensions :: ix -> Dim
- totalElem :: Sz ix -> Int
- consDim :: Int -> Lower ix -> ix
- unconsDim :: ix -> (Int, Lower ix)
- snocDim :: Lower ix -> Int -> ix
- unsnocDim :: ix -> (Lower ix, Int)
- dropDim :: ix -> Dim -> Maybe (Lower ix)
- pullOutDim :: ix -> Dim -> Maybe (Int, Lower ix)
- insertDim :: Lower ix -> Dim -> Int -> Maybe ix
- getDim :: ix -> Dim -> Maybe Int
- setDim :: ix -> Dim -> Int -> Maybe ix
- getIndex :: ix -> Dim -> Maybe Int
- setIndex :: ix -> Dim -> Int -> Maybe ix
- pureIndex :: Int -> ix
- liftIndex2 :: (Int -> Int -> Int) -> ix -> ix -> ix
- liftIndex :: (Int -> Int) -> ix -> ix
- foldlIndex :: (a -> Int -> a) -> a -> ix -> a
- isSafeIndex :: Sz ix -> ix -> Bool
- toLinearIndex :: Sz ix -> ix -> Int
- toLinearIndexAcc :: Int -> ix -> ix -> Int
- fromLinearIndex :: Sz ix -> Int -> ix
- fromLinearIndexAcc :: Sz ix -> Int -> (Int, ix)
- repairIndex :: Sz ix -> ix -> (Int -> Int -> Int) -> (Int -> Int -> Int) -> ix
- iter :: ix -> ix -> ix -> (Int -> Int -> Bool) -> a -> (ix -> a -> a) -> a
- iterM :: Monad m => ix -> ix -> ix -> (Int -> Int -> Bool) -> a -> (ix -> a -> m a) -> m a
- iterM_ :: Monad m => ix -> ix -> ix -> (Int -> Int -> Bool) -> (ix -> m a) -> m ()

- errorIx :: (Show ix, Show ix') => String -> Sz ix -> ix' -> a
- errorSizeMismatch :: (Show ix, Show ix') => String -> Sz ix -> ix' -> a
- zeroIndex :: Index ix => ix
- isSafeSize :: Index ix => Sz ix -> Bool
- isNonEmpty :: Index ix => Sz ix -> Bool
- headDim :: Index ix => ix -> Int
- tailDim :: Index ix => ix -> Lower ix
- lastDim :: Index ix => ix -> Int
- initDim :: Index ix => ix -> Lower ix
- getIndex' :: Index ix => ix -> Dim -> Int
- setIndex' :: Index ix => ix -> Dim -> Int -> ix
- getDim' :: Index ix => ix -> Dim -> Int
- setDim' :: Index ix => ix -> Dim -> Int -> ix
- dropDim' :: Index ix => ix -> Dim -> Lower ix
- pullOutDim' :: Index ix => ix -> Dim -> (Int, Lower ix)
- insertDim' :: Index ix => Lower ix -> Dim -> Int -> ix
- fromDimension :: KnownNat n => Dimension n -> Dim
- getDimension :: IsIndexDimension ix n => ix -> Dimension n -> Int
- setDimension :: IsIndexDimension ix n => ix -> Dimension n -> Int -> ix
- dropDimension :: IsIndexDimension ix n => ix -> Dimension n -> Lower ix
- pullOutDimension :: IsIndexDimension ix n => ix -> Dimension n -> (Int, Lower ix)
- insertDimension :: IsIndexDimension ix n => Lower ix -> Dimension n -> Int -> ix
- iterLinearM :: (Index ix, Monad m) => Sz ix -> Int -> Int -> Int -> (Int -> Int -> Bool) -> a -> (Int -> ix -> a -> m a) -> m a
- iterLinearM_ :: (Index ix, Monad m) => Sz ix -> Int -> Int -> Int -> (Int -> Int -> Bool) -> (Int -> ix -> m ()) -> m ()
- loop :: Int -> (Int -> Bool) -> (Int -> Int) -> a -> (Int -> a -> a) -> a
- loopM :: Monad m => Int -> (Int -> Bool) -> (Int -> Int) -> a -> (Int -> a -> m a) -> m a
- loopM_ :: Monad m => Int -> (Int -> Bool) -> (Int -> Int) -> (Int -> m a) -> m ()
- loopDeepM :: Monad m => Int -> (Int -> Bool) -> (Int -> Int) -> a -> (Int -> a -> m a) -> m a
- splitLinearly :: Int -> Int -> (Int -> Int -> a) -> a
- splitLinearlyWith_ :: Monad m => Int -> (m () -> m a) -> Int -> (Int -> b) -> (Int -> b -> m ()) -> m a
- splitLinearlyWithM_ :: Monad m => Int -> (m () -> m a) -> Int -> (Int -> m b) -> (Int -> b -> m c) -> m a

# Documentation

pattern Ix1 :: Int -> Ix1 Source #

This is a very handy pattern synonym to indicate that any arbitrary whole number is an `Int`

,
i.e. a 1-dimensional index: `(Ix1 i) == (i :: Int)`

2-dimensional index. This also a base index for higher dimensions.

## Instances

pattern Ix2 :: Int -> Int -> Ix2 Source #

2-dimensional index constructor. Useful when `TypeOperators`

extension isn't enabled, or simply
infix notation is inconvenient. `(Ix2 i j) == (i :. j)`

.

3-dimensional type synonym. Useful as a alternative to enabling `DataKinds`

and using type
level Nats.

pattern Ix3 :: Int -> Int -> Int -> Ix3 Source #

3-dimensional index constructor. `(Ix3 i j k) == (i :> j :. k)`

.

pattern Ix4 :: Int -> Int -> Int -> Int -> Ix4 Source #

4-dimensional index constructor. `(Ix4 i j k l) == (i :> j :> k :. l)`

.

pattern Ix5 :: Int -> Int -> Int -> Int -> Int -> Ix5 Source #

5-dimensional index constructor. `(Ix5 i j k l m) = (i :> j :> k :> l :. m)`

.

n-dimensional index. Needs a base case, which is the `Ix2`

.

## Instances

type family Ix (n :: Nat) = r | r -> n where ... Source #

Defines n-dimensional index by relating a general `IxN`

with few base cases.

Stride provides a way to ignore elements of an array if an index is divisible by a
corresponding value in a stride. So, for a `Stride (i :. j)`

only elements with indices will be
kept around:

( 0 :. 0) ( 0 :. j) ( 0 :. 2j) ( 0 :. 3j) ... ( i :. 0) ( i :. j) ( i :. 2j) ( i :. 3j) ... (2i :. 0) (2i :. j) (2i :. 2j) (2i :. 3j) ... ...

Only positive strides make sense, so `Stride`

pattern synonym constructor will prevent a user
from creating a stride with negative or zero values, thus promoting safety of the library.

#### Examples:

- Default and minimal stride of

will have no affect and all elements will kept.`Stride`

(`pureIndex`

1) - If stride is

, then every 2nd element (i.e. with index 1, 3, 5, ..) will be skipped and only elemnts with indices divisible by 2 will be kept around.`Stride`

2 - In case of two dimensions, if what you want is to keep all rows divisible by 5, but keep every
column intact then you'd use
`Stride (5 :. 1)`

.

pattern Stride :: Index ix => ix -> Stride ix Source #

A safe bidirectional pattern synonym for `Stride`

construction that will make sure stride
elements are always positive.

Compute an index with stride using the original size and index

strideStart :: Index ix => Stride ix -> ix -> ix Source #

Adjust strating index according to the stride

Approach to be used near the borders during various transformations. Whenever a function needs information not only about an element of interest, but also about it's neighbors, it will go out of bounds near the array edges, hence is this set of approaches that specify how to handle such situation.

Fill e | Fill in a constant element. ```
outside | Array | outside
(
``` |

Wrap | Wrap around from the opposite border of the array. ```
outside | Array | outside
``` |

Edge | Replicate the element at the edge. ```
outside | Array | outside
``` |

Reflect | Mirror like reflection. ```
outside | Array | outside
``` |

Continue | Also mirror like reflection, but without repeating the edge element. ```
outside | Array | outside
``` |

:: Index ix | |

=> Border e | Broder resolution technique |

-> Sz ix | Size |

-> (ix -> e) | Index function that produces an element |

-> ix | Index |

-> e |

Apply a border resolution technique to an index

A way to select Array dimension at a value level.

type IsIndexDimension ix n = (1 <= n, n <= Dimensions ix, Index ix, KnownNat n) Source #

A type level constraint that ensures index is indeed valid and that supplied dimension can be safely used with it.

Zero-dimension, i.e. a scalar. Can't really be used directly as there are no instances of
`Index`

for it, and is included for completeness.

type family Lower ix :: * Source #

This type family will always point to a type for a dimension that is one lower than the type argument.

## Instances

type Lower Ix5T Source # | |

Defined in Data.Massiv.Core.Index.Class | |

type Lower Ix4T Source # | |

Defined in Data.Massiv.Core.Index.Class | |

type Lower Ix3T Source # | |

Defined in Data.Massiv.Core.Index.Class | |

type Lower Ix2T Source # | |

Defined in Data.Massiv.Core.Index.Class | |

type Lower Ix1T Source # | |

Defined in Data.Massiv.Core.Index.Class | |

type Lower Ix2 Source # | |

Defined in Data.Massiv.Core.Index.Ix | |

type Lower (IxN n) Source # | |

Defined in Data.Massiv.Core.Index.Ix |

class (Eq ix, Ord ix, Show ix, NFData ix) => Index ix where Source #

This is bread and butter of multi-dimensional array indexing. It is unlikely that any of the functions in this class will be useful to a regular user, unless general algorithms are being implemented that do span multiple dimensions.

dimensions, totalElem, consDim, unconsDim, snocDim, unsnocDim, pullOutDim, insertDim, pureIndex, liftIndex2

type Dimensions ix :: Nat Source #

dimensions :: ix -> Dim Source #

Dimensions of an array that has this index type, i.e. what is the dimensionality.

totalElem :: Sz ix -> Int Source #

Total number of elements in an array of this size.

consDim :: Int -> Lower ix -> ix Source #

Prepend a dimension to the index

unconsDim :: ix -> (Int, Lower ix) Source #

Take a dimension from the index from the outside

snocDim :: Lower ix -> Int -> ix Source #

Apppend a dimension to the index

unsnocDim :: ix -> (Lower ix, Int) Source #

Take a dimension from the index from the inside

dropDim :: ix -> Dim -> Maybe (Lower ix) Source #

Remove a dimension from the index

pullOutDim :: ix -> Dim -> Maybe (Int, Lower ix) Source #

Pull out value at specified dimension from the index, thus also lowering it dimensionality.

insertDim :: Lower ix -> Dim -> Int -> Maybe ix Source #

Insert a dimension into the index

getDim :: ix -> Dim -> Maybe Int Source #

Extract the value index has at specified dimension.

setDim :: ix -> Dim -> Int -> Maybe ix Source #

Set the value for an index at specified dimension.

getIndex :: ix -> Dim -> Maybe Int Source #

Deprecated: In favor of `getDim`

Extract the value index has at specified dimension. To be deprecated.

setIndex :: ix -> Dim -> Int -> Maybe ix Source #

Deprecated: In favor of `setDim`

Set the value for an index at specified dimension. To be deprecated.

pureIndex :: Int -> ix Source #

Lift an `Int`

to any index by replicating the value as many times as there are dimensions.

liftIndex2 :: (Int -> Int -> Int) -> ix -> ix -> ix Source #

Zip together two indices with a function

liftIndex :: (Int -> Int) -> ix -> ix Source #

Map a function over an index

foldlIndex :: (a -> Int -> a) -> a -> ix -> a Source #

foldlIndex :: Index (Lower ix) => (a -> Int -> a) -> a -> ix -> a Source #

Check whether index is within the size.

Check whether index is within the size.

Convert linear index from size and index

Convert linear index from size and index

toLinearIndexAcc :: Int -> ix -> ix -> Int Source #

Convert linear index from size and index with an accumulator. Currently is useless and will likley be removed in future versions.

toLinearIndexAcc :: Index (Lower ix) => Int -> ix -> ix -> Int Source #

Convert linear index from size and index with an accumulator. Currently is useless and will likley be removed in future versions.

fromLinearIndex :: Sz ix -> Int -> ix Source #

Compute an index from size and linear index

fromLinearIndex :: Index (Lower ix) => Sz ix -> Int -> ix Source #

Compute an index from size and linear index

fromLinearIndexAcc :: Sz ix -> Int -> (Int, ix) Source #

Compute an index from size and linear index using an accumulator, thus trying to optimize for tail recursion while getting the index computed.

fromLinearIndexAcc :: Index (Lower ix) => Sz ix -> Int -> (Int, ix) Source #

Compute an index from size and linear index using an accumulator, thus trying to optimize for tail recursion while getting the index computed.

:: Sz ix | Size |

-> ix | Index |

-> (Int -> Int -> Int) | Repair when below zero |

-> (Int -> Int -> Int) | Repair when higher than size |

-> ix |

A way to make sure index is withing the bounds for the supplied size. Takes two functions that will be invoked whenever index (2nd arg) is outsize the supplied size (1st arg)

:: Index (Lower ix) | |

=> Sz ix | Size |

-> ix | Index |

-> (Int -> Int -> Int) | Repair when below zero |

-> (Int -> Int -> Int) | Repair when higher than size |

-> ix |

A way to make sure index is withing the bounds for the supplied size. Takes two functions that will be invoked whenever index (2nd arg) is outsize the supplied size (1st arg)

iter :: ix -> ix -> ix -> (Int -> Int -> Bool) -> a -> (ix -> a -> a) -> a Source #

Iterator for the index. Same as `iterM`

, but pure.

:: Monad m | |

=> ix | Start index |

-> ix | End index |

-> ix | Increment |

-> (Int -> Int -> Bool) | Continue iterating while predicate is True (eg. until end of row) |

-> a | Initial value for an accumulator |

-> (ix -> a -> m a) | Accumulator function |

-> m a |

This function is what makes it possible to iterate over an array of any dimension.

:: (Index (Lower ix), Monad m) | |

=> ix | Start index |

-> ix | End index |

-> ix | Increment |

-> (Int -> Int -> Bool) | Continue iterating while predicate is True (eg. until end of row) |

-> a | Initial value for an accumulator |

-> (ix -> a -> m a) | Accumulator function |

-> m a |

This function is what makes it possible to iterate over an array of any dimension.

iterM_ :: Monad m => ix -> ix -> ix -> (Int -> Int -> Bool) -> (ix -> m a) -> m () Source #

Same as `iterM`

, but don't bother with accumulator and return value.

iterM_ :: (Index (Lower ix), Monad m) => ix -> ix -> ix -> (Int -> Int -> Bool) -> (ix -> m a) -> m () Source #

Same as `iterM`

, but don't bother with accumulator and return value.

## Instances

errorIx :: (Show ix, Show ix') => String -> Sz ix -> ix' -> a Source #

Helper function for throwing out of bounds errors

errorSizeMismatch :: (Show ix, Show ix') => String -> Sz ix -> ix' -> a Source #

Helper function for throwing error when sizes do not match

isSafeSize :: Index ix => Sz ix -> Bool Source #

Checks whether the size is valid.

**Note** Will be removed in *massiv-0.3.0*

isNonEmpty :: Index ix => Sz ix -> Bool Source #

Checks whether array with this size can hold at least one element.

getDimension :: IsIndexDimension ix n => ix -> Dimension n -> Int Source #

Type safe way to extract value of index at a particular dimension.

*Since: 0.2.4*

setDimension :: IsIndexDimension ix n => ix -> Dimension n -> Int -> ix Source #

Type safe way to set value of index at a particular dimension.

*Since: 0.2.4*

dropDimension :: IsIndexDimension ix n => ix -> Dimension n -> Lower ix Source #

Type safe way of dropping a particular dimension, thus lowering index dimensionality.

*Since: 0.2.4*

pullOutDimension :: IsIndexDimension ix n => ix -> Dimension n -> (Int, Lower ix) Source #

Type safe way of pulling out a particular dimension, thus lowering index dimensionality and returning the value at specified dimension.

*Since: 0.2.4*

insertDimension :: IsIndexDimension ix n => Lower ix -> Dimension n -> Int -> ix Source #

Type safe way of inserting a particular dimension, thus raising index dimensionality.

*Since: 0.2.5*

:: (Index ix, Monad m) | |

=> Sz ix | Size |

-> Int | Linear start |

-> Int | Linear end |

-> Int | Increment |

-> (Int -> Int -> Bool) | Continuation condition (continue if True) |

-> a | Accumulator |

-> (Int -> ix -> a -> m a) | |

-> m a |

Iterate over N-dimensional space lenarly from start to end in row-major fashion with an accumulator

:: (Index ix, Monad m) | |

=> Sz ix | Size |

-> Int | Start |

-> Int | End |

-> Int | Increment |

-> (Int -> Int -> Bool) | Continuation condition |

-> (Int -> ix -> m ()) | Monadic action that takes index in both forms |

-> m () |

Same as `iterLinearM`

, except without an accumulator.

loop :: Int -> (Int -> Bool) -> (Int -> Int) -> a -> (Int -> a -> a) -> a Source #

Efficient loop with an accumulator

loopM :: Monad m => Int -> (Int -> Bool) -> (Int -> Int) -> a -> (Int -> a -> m a) -> m a Source #

Very efficient monadic loop with an accumulator

loopM_ :: Monad m => Int -> (Int -> Bool) -> (Int -> Int) -> (Int -> m a) -> m () Source #

Efficient monadic loop. Result of each iteration is discarded.

loopDeepM :: Monad m => Int -> (Int -> Bool) -> (Int -> Int) -> a -> (Int -> a -> m a) -> m a Source #

Less efficient monadic loop with an accumulator that reverses the direction of action application