-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Mutable and immutable dense multidimensional arrays -- -- Multidimentional array library build on top of the vector package, -- using indices from the linear package. Native support for mutable -- arrays, stencils and parallel computation. @package dense @version 0.1.0.1 -- | This module provides a class for types that can be converted to and -- from linear indexes. -- -- The default instances are defined in row-major order. module Data.Dense.Index -- | A Layout is the full size of an array. This alias is used to -- help distinguish between the layout of an array and an index (usually -- just l Int) in a type signature. type Layout f = f Int -- | Class for types that can be converted to and from linear indexes. class (Eq1 f, Additive f, Traversable f) => Shape f -- | Convert a shape to its linear index using the Layout. shapeToIndex :: Shape f => Layout f -> f Int -> Int -- | Convert a linear index to a shape the Layout. shapeFromIndex :: Shape f => Layout f -> Int -> f Int -- | Calculate the intersection of two shapes. shapeIntersect :: Shape f => Layout f -> Layout f -> Layout f -- | Increment a shape by one. It is assumed that the provided index is -- inRange. unsafeShapeStep :: Shape f => Layout f -> f Int -> f Int -- | Increment a shape by one. It is assumed that the provided index is -- inRange. shapeStep :: Shape f => Layout f -> f Int -> Maybe (f Int) -- | Increment a shape by one between the two bounds shapeStepBetween :: Shape f => f Int -> Layout f -> f Int -> Maybe (f Int) -- | inRange ex i checks i < ex for every coordinate -- of f. shapeInRange :: Shape f => Layout f -> f Int -> Bool -- | The number of elements in a shape. shapeSize :: Shape f => Layout f -> Int -- | toIndex l and fromIndex l form two -- halfs of an isomorphism. indexIso :: Shape f => Layout f -> Iso' (f Int) Int -- | indexes for a Shape. shapeIndexes :: Shape f => IndexedFold Int (Layout f) (f Int) -- | indexesFrom for a Shape. shapeIndexesFrom :: Shape f => f Int -> IndexedFold Int (Layout f) (f Int) -- | indexesBetween for a Shape. shapeIndexesBetween :: Shape f => f Int -> f Int -> IndexedFold Int (Layout f) (f Int) -- | Class of things that have a Layout. This means we can use the -- same functions for the various different arrays in the library. class Shape f => HasLayout f a | a -> f -- | Lens onto the Layout of something. layout :: HasLayout f a => Lens' a (Layout f) -- | Lens onto the Layout of something. layout :: (HasLayout f a, a ~ f Int) => (Layout f -> g (Layout f)) -> a -> g a -- | Get the extent of an array. -- --
--   extent :: Array v f a    -> f Int
--   extent :: MArray v f s a -> f Int
--   extent :: Delayed f a    -> f Int
--   extent :: Focused f a    -> f Int
--   
extent :: HasLayout f a => a -> f Int -- | Get the total number of elements in an array. -- --
--   size :: Array v f a    -> Int
--   size :: MArray v f s a -> Int
--   size :: Delayed f a    -> Int
--   size :: Focused f a    -> Int
--   
size :: HasLayout f a => a -> Int -- | Indexed fold for all the indexes in the layout. indexes :: HasLayout f a => IndexedFold Int a (f Int) -- | Indexed fold between the two indexes where the index is the linear -- index for the original layout. indexesBetween :: HasLayout f a => f Int -> f Int -> IndexedFold Int a (f Int) -- | Indexed fold starting starting from some point, where the index is the -- linear index for the original layout. indexesFrom :: HasLayout f a => f Int -> IndexedFold Int a (f Int) -- | Exceptions generated by array operations data ArrayException -- | An attempt was made to index an array outside its declared bounds. IndexOutOfBounds :: String -> ArrayException -- | An attempt was made to index an array outside its declared bounds. -- --
--   _IndexOutOfBounds_ArrayException . _IndexOutOfBounds
--   
-- --
--   _IndexOutOfBounds :: Prism' ArrayException String
--   _IndexOutOfBounds :: Prism' SomeException  String
--   
_IndexOutOfBounds :: AsArrayException t => Prism' t String -- | boundsCheck l i performs a bounds check for index i -- and layout l. Throws an IndexOutOfBounds exception -- when out of range in the form (i, l). This can be caught with -- the _IndexOutOfBounds prism. -- --
--   >>> boundsCheck (V2 3 5) (V2 1 4) "in range"
--   "in range"
--   
-- --
--   >>> boundsCheck (V2 10 20) (V2 10 5) "in bounds"
--   "*** Exception: array index out of range: (V2 10 5, V2 10 20)
--   
-- --
--   >>> catching _IndexOutOfBounds (boundsCheck (V1 2) (V1 2) (putStrLn "in range")) print
--   "(V1 2, V1 2)"
--   
-- -- The output format is suitable to be read using the _Show prism: -- --
--   >>> trying (_IndexOutOfBounds . _Show) (boundsCheck (V1 2) (V1 20) (putStrLn "in range")) :: IO (Either (V1 Int, V1 Int) ())
--   Left (V1 20,V1 2)
--   
boundsCheck :: Shape l => Layout l -> l Int -> a -> a -- | Thrown when two sizes that should match, don't. data SizeMissmatch SizeMissmatch :: String -> SizeMissmatch -- | Exception thown from missmatching sizes. class AsSizeMissmatch t -- | Extract information about an SizeMissmatch. -- --
--   _SizeMissmatch :: Prism' SizeMissmatch String
--   _SizeMissmatch :: Prism' SomeException String
--   
_SizeMissmatch :: AsSizeMissmatch t => Prism' t String -- | Check the sizes are equal. If not, throw SizeMissmatch. sizeMissmatch :: Int -> Int -> String -> a -> a -- | Show a shape in the form VN i1 i2 .. iN where N is -- the length of the shape. showShape :: Shape f => f Int -> String instance Data.Dense.Index.AsSizeMissmatch Data.Dense.Index.SizeMissmatch instance Data.Dense.Index.AsSizeMissmatch GHC.Exception.Type.SomeException instance GHC.Exception.Type.Exception Data.Dense.Index.SizeMissmatch instance GHC.Show.Show Data.Dense.Index.SizeMissmatch instance (i GHC.Types.~ GHC.Types.Int) => Data.Dense.Index.HasLayout Linear.V0.V0 (Linear.V0.V0 i) instance (i GHC.Types.~ GHC.Types.Int) => Data.Dense.Index.HasLayout Linear.V1.V1 (Linear.V1.V1 i) instance (i GHC.Types.~ GHC.Types.Int) => Data.Dense.Index.HasLayout Linear.V2.V2 (Linear.V2.V2 i) instance (i GHC.Types.~ GHC.Types.Int) => Data.Dense.Index.HasLayout Linear.V3.V3 (Linear.V3.V3 i) instance (i GHC.Types.~ GHC.Types.Int) => Data.Dense.Index.HasLayout Linear.V4.V4 (Linear.V4.V4 i) instance Data.Dense.Index.Shape Linear.V0.V0 instance Data.Dense.Index.Shape Linear.V1.V1 instance Data.Dense.Index.Shape Linear.V2.V2 instance Data.Dense.Index.Shape Linear.V3.V3 instance Data.Dense.Index.Shape Linear.V4.V4 -- | This module provides generic functions over mutable multidimensional -- arrays. module Data.Dense.Mutable -- | A mutable array with a shape. data MArray v l s a MArray :: !Layout l -> !v s a -> MArray v l s a -- | Unboxed mutable array. type UMArray = MArray MVector -- | Storable mutable array. type SMArray = MArray MVector -- | Boxed mutable array. type BMArray = MArray MVector -- | Primitive mutable array. type PMArray = MArray MVector -- | Lens onto the shape of the vector. The total size of the layout _must_ -- remain the same or an error is thrown. mlayout :: (Shape f, Shape f') => Lens (MArray v f s a) (MArray v f' s a) (Layout f) (Layout f') -- | Indexed lens over the underlying vector of an array. The index is the -- extent of the array. You must not change the length of -- the vector, otherwise an error will be thrown. mvector :: (MVector v a, MVector w b) => IndexedLens (Layout f) (MArray v f s a) (MArray w f t b) (v s a) (w t b) -- | New mutable array with shape l. new :: (PrimMonad m, Shape f, MVector v a) => Layout f -> m (MArray v f (PrimState m) a) -- | New mutable array with shape l filled with element -- a. replicate :: (PrimMonad m, Shape f, MVector v a) => Layout f -> a -> m (MArray v f (PrimState m) a) -- | New mutable array with shape l filled with result of monadic -- action a. replicateM :: (PrimMonad m, Shape f, MVector v a) => Layout f -> m a -> m (MArray v f (PrimState m) a) -- | Clone a mutable array, making a new, separate mutable array. clone :: (PrimMonad m, MVector v a) => MArray v f (PrimState m) a -> m (MArray v f (PrimState m) a) -- | Read a mutable array at element l. read :: (PrimMonad m, Shape f, MVector v a) => MArray v f (PrimState m) a -> f Int -> m a -- | Read a mutable array at element i by indexing the internal -- vector. linearRead :: (PrimMonad m, MVector v a) => MArray v f (PrimState m) a -> Int -> m a -- | read without bounds checking. unsafeRead :: (PrimMonad m, Shape f, MVector v a) => MArray v f (PrimState m) a -> f Int -> m a -- | linearRead without bounds checking. unsafeLinearRead :: (PrimMonad m, MVector v a) => MArray v f (PrimState m) a -> Int -> m a -- | Write a mutable array at element l. write :: (PrimMonad m, Shape f, MVector v a) => MArray v f (PrimState m) a -> f Int -> a -> m () -- | Write a mutable array at element i by indexing the internal -- vector. linearWrite :: (PrimMonad m, MVector v a) => MArray v f (PrimState m) a -> Int -> a -> m () -- | write without bounds checking. unsafeWrite :: (PrimMonad m, Shape f, MVector v a) => MArray v f (PrimState m) a -> f Int -> a -> m () -- | linearWrite without bounds checking. unsafeLinearWrite :: (PrimMonad m, MVector v a) => MArray v f (PrimState m) a -> Int -> a -> m () -- | Modify a mutable array at element l by applying a function. modify :: (PrimMonad m, Shape f, MVector v a) => MArray v f (PrimState m) a -> f Int -> (a -> a) -> m () -- | Modify a mutable array at element i by applying a function. linearModify :: (PrimMonad m, MVector v a) => MArray v f (PrimState m) a -> Int -> (a -> a) -> m () -- | modify without bounds checking. unsafeModify :: (PrimMonad m, Shape f, MVector v a) => MArray v f (PrimState m) a -> f Int -> (a -> a) -> m () -- | linearModify without bounds checking. unsafeLinearModify :: (PrimMonad m, MVector v a) => MArray v f (PrimState m) a -> Int -> (a -> a) -> m () -- | Swap two elements in a mutable array. swap :: (PrimMonad m, Shape f, MVector v a) => MArray v f (PrimState m) a -> f Int -> f Int -> m () -- | Swap two elements in a mutable array by indexing the internal vector. linearSwap :: (PrimMonad m, MVector v a) => MArray v f (PrimState m) a -> Int -> Int -> m () -- | swap without bounds checking. unsafeSwap :: (PrimMonad m, Shape f, MVector v a) => MArray v f (PrimState m) a -> f Int -> f Int -> m () -- | linearSwap without bounds checking. unsafeLinearSwap :: (PrimMonad m, MVector v a) => MArray v f (PrimState m) a -> Int -> Int -> m () -- | Replace the element at the give position and return the old element. exchange :: (PrimMonad m, Shape f, MVector v a) => MArray v f (PrimState m) a -> f Int -> a -> m a -- | Replace the element at the give position and return the old element. linearExchange :: (PrimMonad m, MVector v a) => MArray v f (PrimState m) a -> Int -> a -> m a -- | Replace the element at the give position and return the old element. unsafeExchange :: (PrimMonad m, Shape f, MVector v a) => MArray v f (PrimState m) a -> f Int -> a -> m a -- | Replace the element at the give position and return the old element. unsafeLinearExchange :: (PrimMonad m, MVector v a) => MArray v f (PrimState m) a -> Int -> a -> m a -- | Set all elements in a mutable array to a constant value. set :: (PrimMonad m, MVector v a) => MArray v f (PrimState m) a -> a -> m () -- | Clear the elements of a mutable array. This is usually a no-op for -- unboxed arrays. clear :: (PrimMonad m, MVector v a) => MArray v f (PrimState m) a -> m () -- | Copy all elements from one array into another. copy :: (PrimMonad m, MVector v a) => MArray v f (PrimState m) a -> MArray v f (PrimState m) a -> m () instance Data.Dense.Index.Shape f => Data.Dense.Index.HasLayout f (Data.Dense.Mutable.MArray v f s a) instance (Data.Vector.Generic.Mutable.Base.MVector v a, f GHC.Types.~ Linear.V1.V1) => Data.Vector.Generic.Mutable.Base.MVector (Data.Dense.Mutable.MArray v f) a -- | Base module for multidimensional arrays. This module exports the -- constructors for the Array data type. -- -- Also, to prevent this module becomming too large, only the data types -- and the functions nessesary for the instances are defined here. All -- other functions are defined in Data.Dense.Generic. module Data.Dense.Base -- | An Array is a vector with a shape. data Array v f a Array :: !Layout f -> !v a -> Array v f a -- | The vector is the boxed vector. type Boxed v = v ~ Vector -- | Indexed lens over the underlying vector of an array. The index is the -- extent of the array. You must _not_ change the length of the -- vector, otherwise an error will be thrown (even for V1 layouts, -- use flat for V1). vector :: (Vector v a, Vector w b) => IndexedLens (Layout f) (Array v f a) (Array w f b) (v a) (w b) -- | Indexed traversal over the elements of an array. The index is the -- current position in the array. values :: (Shape f, Vector v a, Vector w b) => IndexedTraversal (f Int) (Array v f a) (Array w f b) a b -- | O(1) Unsafely convert an immutable array to a mutable one without -- copying. The immutable array may not be used after this operation. unsafeThaw :: (PrimMonad m, Vector v a) => Array v f a -> m (MArray (Mutable v) f (PrimState m) a) -- | O(1) Unsafe convert a mutable array to an immutable one without -- copying. The mutable array may not be used after this operation. unsafeFreeze :: (PrimMonad m, Vector v a) => MArray (Mutable v) f (PrimState m) a -> m (Array v f a) -- | A delayed representation of an array. This useful for mapping over an -- array in parallel. data Delayed f a Delayed :: !Layout f -> (f Int -> a) -> Delayed f a -- | Turn a material array into a delayed one with the same shape. delay :: (Vector v a, Shape f) => Array v f a -> Delayed f a -- | Parallel manifestation of a delayed array into a material one. manifest :: (Vector v a, Shape f) => Delayed f a -> Array v f a -- | Generate a Delayed array using the given Layout and -- construction function. genDelayed :: Layout f -> (f Int -> a) -> Delayed f a -- | Index a delayed array, returning a IndexOutOfBounds exception -- if the index is out of range. indexDelayed :: Shape f => Delayed f a -> f Int -> a -- | A delayed representation of an array with a focus on a single element. -- This element is the target of extract. data Focused f a Focused :: !f Int -> !Delayed f a -> Focused f a instance GHC.Base.Functor (Data.Dense.Base.Delayed f) instance GHC.Base.Functor (Data.Dense.Base.Focused f) instance (Data.Typeable.Internal.Typeable f, Data.Typeable.Internal.Typeable v, Data.Typeable.Internal.Typeable a, Data.Data.Data (f GHC.Types.Int), Data.Data.Data (v a)) => Data.Data.Data (Data.Dense.Base.Array v f a) instance Data.Dense.Index.Shape f => Data.Dense.Index.HasLayout f (Data.Dense.Base.Focused f a) instance Data.Dense.Index.Shape f => Control.Comonad.Comonad (Data.Dense.Base.Focused f) instance Data.Dense.Index.Shape f => Data.Functor.Extend.Extend (Data.Dense.Base.Focused f) instance Data.Dense.Index.Shape f => Control.Comonad.Store.Class.ComonadStore (f GHC.Types.Int) (Data.Dense.Base.Focused f) instance (Data.Dense.Index.Shape f, Data.Functor.Classes.Show1 f, GHC.Show.Show a) => GHC.Show.Show (Data.Dense.Base.Focused f a) instance Data.Dense.Index.Shape f => Data.Foldable.Foldable (Data.Dense.Base.Focused f) instance Data.Dense.Index.Shape f => Data.Traversable.Traversable (Data.Dense.Base.Focused f) instance Data.Dense.Index.Shape f => Control.Lens.Indexed.FunctorWithIndex (f GHC.Types.Int) (Data.Dense.Base.Focused f) instance Data.Dense.Index.Shape f => Control.Lens.Indexed.FoldableWithIndex (f GHC.Types.Int) (Data.Dense.Base.Focused f) instance Data.Dense.Index.Shape f => Control.Lens.Indexed.TraversableWithIndex (f GHC.Types.Int) (Data.Dense.Base.Focused f) instance Data.Dense.Index.Shape f => Control.Lens.At.Ixed (Data.Dense.Base.Focused f a) instance Data.Dense.Index.Shape f => Data.Dense.Index.HasLayout f (Data.Dense.Base.Delayed f a) instance Data.Dense.Index.Shape f => Data.Foldable.Foldable (Data.Dense.Base.Delayed f) instance (Data.Dense.Index.Shape f, Data.Functor.Classes.Show1 f, GHC.Show.Show a) => GHC.Show.Show (Data.Dense.Base.Delayed f a) instance Data.Dense.Index.Shape f => Data.Traversable.Traversable (Data.Dense.Base.Delayed f) instance Data.Dense.Index.Shape f => Data.Functor.Bind.Class.Apply (Data.Dense.Base.Delayed f) instance Data.Dense.Index.Shape f => Linear.Vector.Additive (Data.Dense.Base.Delayed f) instance Data.Dense.Index.Shape f => Linear.Metric.Metric (Data.Dense.Base.Delayed f) instance Control.Lens.Indexed.FunctorWithIndex (f GHC.Types.Int) (Data.Dense.Base.Delayed f) instance Data.Dense.Index.Shape f => Control.Lens.Indexed.FoldableWithIndex (f GHC.Types.Int) (Data.Dense.Base.Delayed f) instance Data.Dense.Index.Shape f => Control.Lens.Indexed.TraversableWithIndex (f GHC.Types.Int) (Data.Dense.Base.Delayed f) instance Data.Dense.Index.Shape f => Control.Lens.Each.Each (Data.Dense.Base.Delayed f a) (Data.Dense.Base.Delayed f b) a b instance Data.Dense.Index.Shape f => Control.Lens.Empty.AsEmpty (Data.Dense.Base.Delayed f a) instance Data.Dense.Index.Shape f => Control.Lens.At.Ixed (Data.Dense.Base.Delayed f a) instance Data.Dense.Base.Boxed v => GHC.Base.Functor (Data.Dense.Base.Array v f) instance Data.Dense.Base.Boxed v => Data.Foldable.Foldable (Data.Dense.Base.Array v f) instance Data.Dense.Base.Boxed v => Data.Traversable.Traversable (Data.Dense.Base.Array v f) instance (Data.Dense.Base.Boxed v, Data.Functor.Classes.Eq1 f) => Data.Functor.Classes.Eq1 (Data.Dense.Base.Array v f) instance (Data.Dense.Base.Boxed v, Data.Functor.Classes.Read1 f) => Data.Functor.Classes.Read1 (Data.Dense.Base.Array v f) instance (Data.Dense.Base.Boxed v, Data.Dense.Index.Shape f) => Control.Lens.Indexed.FunctorWithIndex (f GHC.Types.Int) (Data.Dense.Base.Array v f) instance (Data.Dense.Base.Boxed v, Data.Dense.Index.Shape f) => Control.Lens.Indexed.FoldableWithIndex (f GHC.Types.Int) (Data.Dense.Base.Array v f) instance (Data.Dense.Base.Boxed v, Data.Dense.Index.Shape f) => Control.Lens.Indexed.TraversableWithIndex (f GHC.Types.Int) (Data.Dense.Base.Array v f) instance (Data.Dense.Base.Boxed v, Data.Dense.Index.Shape f, Data.Bytes.Serial.Serial1 f) => Data.Bytes.Serial.Serial1 (Data.Dense.Base.Array v f) instance Data.Dense.Index.Shape f => Data.Dense.Index.HasLayout f (Data.Dense.Base.Array v f a) instance (Data.Vector.Generic.Base.Vector v a, Data.Functor.Classes.Eq1 f, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.Dense.Base.Array v f a) instance (Data.Vector.Generic.Base.Vector v a, Data.Functor.Classes.Show1 f, GHC.Show.Show a) => GHC.Show.Show (Data.Dense.Base.Array v f a) instance (Data.Dense.Index.Shape f, Data.Vector.Generic.Base.Vector v a) => Control.Lens.At.Ixed (Data.Dense.Base.Array v f a) instance (Data.Vector.Generic.Base.Vector v a, Data.Vector.Generic.Base.Vector v b) => Control.Lens.Each.Each (Data.Dense.Base.Array v f a) (Data.Dense.Base.Array v f b) a b instance (Data.Dense.Index.Shape f, Data.Vector.Generic.Base.Vector v a) => Control.Lens.Empty.AsEmpty (Data.Dense.Base.Array v f a) instance (Data.Vector.Generic.Base.Vector v a, Data.Functor.Classes.Read1 f, GHC.Read.Read a) => GHC.Read.Read (Data.Dense.Base.Array v f a) instance (Control.DeepSeq.NFData (f GHC.Types.Int), Control.DeepSeq.NFData (v a)) => Control.DeepSeq.NFData (Data.Dense.Base.Array v f a) instance (Data.Vector.Generic.Base.Vector v a, f GHC.Types.~ Linear.V1.V1) => Data.Vector.Generic.Base.Vector (Data.Dense.Base.Array v f) a instance (Data.Vector.Generic.Base.Vector v a, Data.Dense.Index.Shape f, Data.Bytes.Serial.Serial1 f, Data.Bytes.Serial.Serial a) => Data.Bytes.Serial.Serial (Data.Dense.Base.Array v f a) instance (Data.Vector.Generic.Base.Vector v a, Data.Dense.Index.Shape f, Data.Binary.Class.Binary (f GHC.Types.Int), Data.Binary.Class.Binary a) => Data.Binary.Class.Binary (Data.Dense.Base.Array v f a) instance (Data.Vector.Generic.Base.Vector v a, Data.Dense.Index.Shape f, Data.Serialize.Serialize (f GHC.Types.Int), Data.Serialize.Serialize a) => Data.Serialize.Serialize (Data.Dense.Base.Array v f a) instance (Data.Vector.Generic.Base.Vector v a, Data.Foldable.Foldable f, Data.Hashable.Class.Hashable a) => Data.Hashable.Class.Hashable (Data.Dense.Base.Array v f a) -- | This module provides generic functions over multidimensional arrays. module Data.Dense.Generic -- | An Array is a vector with a shape. data Array v f a -- | Class for types that can be converted to and from linear indexes. class (Eq1 f, Additive f, Traversable f) => Shape f -- | Convert a shape to its linear index using the Layout. shapeToIndex :: Shape f => Layout f -> f Int -> Int -- | Convert a linear index to a shape the Layout. shapeFromIndex :: Shape f => Layout f -> Int -> f Int -- | Calculate the intersection of two shapes. shapeIntersect :: Shape f => Layout f -> Layout f -> Layout f -- | Increment a shape by one. It is assumed that the provided index is -- inRange. unsafeShapeStep :: Shape f => Layout f -> f Int -> f Int -- | Increment a shape by one. It is assumed that the provided index is -- inRange. shapeStep :: Shape f => Layout f -> f Int -> Maybe (f Int) -- | Increment a shape by one between the two bounds shapeStepBetween :: Shape f => f Int -> Layout f -> f Int -> Maybe (f Int) -- | inRange ex i checks i < ex for every coordinate -- of f. shapeInRange :: Shape f => Layout f -> f Int -> Bool -- | The number of elements in a shape. shapeSize :: Shape f => Layout f -> Int -- | Boxed array. type BArray = Array Vector -- | Unboxed array. type UArray = Array Vector -- | Storeable array. type SArray = Array Vector -- | Prim array. type PArray = Array Vector -- | Class of things that have a Layout. This means we can use the -- same functions for the various different arrays in the library. class Shape f => HasLayout f a | a -> f -- | Lens onto the Layout of something. layout :: HasLayout f a => Lens' a (Layout f) -- | Lens onto the Layout of something. layout :: (HasLayout f a, a ~ f Int) => (Layout f -> g (Layout f)) -> a -> g a -- | A Layout is the full size of an array. This alias is used to -- help distinguish between the layout of an array and an index (usually -- just l Int) in a type signature. type Layout f = f Int -- | Get the extent of an array. -- --
--   extent :: Array v f a    -> f Int
--   extent :: MArray v f s a -> f Int
--   extent :: Delayed f a    -> f Int
--   extent :: Focused f a    -> f Int
--   
extent :: HasLayout f a => a -> f Int -- | Get the total number of elements in an array. -- --
--   size :: Array v f a    -> Int
--   size :: MArray v f s a -> Int
--   size :: Delayed f a    -> Int
--   size :: Focused f a    -> Int
--   
size :: HasLayout f a => a -> Int -- | Indexed fold for all the indexes in the layout. indexes :: HasLayout f a => IndexedFold Int a (f Int) -- | Indexed fold starting starting from some point, where the index is the -- linear index for the original layout. indexesFrom :: HasLayout f a => f Int -> IndexedFold Int a (f Int) -- | Indexed fold between the two indexes where the index is the linear -- index for the original layout. indexesBetween :: HasLayout f a => f Int -> f Int -> IndexedFold Int a (f Int) -- | Indexed lens over the underlying vector of an array. The index is the -- extent of the array. You must _not_ change the length of the -- vector, otherwise an error will be thrown (even for V1 layouts, -- use flat for V1). vector :: (Vector v a, Vector w b) => IndexedLens (Layout f) (Array v f a) (Array w f b) (v a) (w b) -- | Indexed traversal over the elements of an array. The index is the -- current position in the array. values :: (Shape f, Vector v a, Vector w b) => IndexedTraversal (f Int) (Array v f a) (Array w f b) a b -- | Same as values but restrictive in the vector type. values' :: (Shape f, Vector v a, Vector v b) => IndexedTraversal (f Int) (Array v f a) (Array v f b) a b -- | Traverse over the values between two indexes. valuesBetween :: (Shape f, Vector v a) => f Int -> f Int -> IndexedTraversal' (f Int) (Array v f a) a -- | 1D arrays are just vectors. You are free to change the length of the -- vector when going over this Iso (unlike -- linear). -- -- Note that V1 arrays are an instance of Vector so you can -- use any of the functions in Data.Vector.Generic on them without -- needing to convert. flat :: Vector w b => Iso (Array v V1 a) (Array w V1 b) (v a) (w b) -- | Contruct a flat array from a list. (This is just fromList from -- Generic.) fromList :: Vector v a => [a] -> Array v V1 a -- | O(n) Convert the first n elements of a list to an Array with -- the given shape. Returns Nothing if there are not enough -- elements in the list. fromListInto :: (Shape f, Vector v a) => Layout f -> [a] -> Maybe (Array v f a) -- | O(n) Convert the first n elements of a list to an Array with -- the given shape. Throw an error if the list is not long enough. fromListInto_ :: (Shape f, Vector v a) => Layout f -> [a] -> Array v f a -- | Create an array from a vector and a layout. Return -- Nothing if the vector is not the right shape. fromVectorInto :: (Shape f, Vector v a) => Layout f -> v a -> Maybe (Array v f a) -- | Create an array from a vector and a layout. Throws an -- error if the vector is not the right shape. fromVectorInto_ :: (Shape f, Vector v a) => Layout f -> v a -> Array v f a -- | O(n) Array of the given shape with the same value in each position. replicate :: (Shape f, Vector v a) => f Int -> a -> Array v f a -- | O(n) Construct an array of the given shape by applying the function to -- each index. generate :: (Shape f, Vector v a) => Layout f -> (f Int -> a) -> Array v f a -- | O(n) Construct an array of the given shape by applying the function to -- each index. linearGenerate :: (Shape f, Vector v a) => Layout f -> (Int -> a) -> Array v f a -- | Execute the monadic action and freeze the resulting array. create :: Vector v a => (forall s. ST s (MArray (Mutable v) f s a)) -> Array v f a -- | Execute the monadic action and freeze the resulting array. createT :: (Vector v a, Traversable t) => (forall s. ST s (t (MArray (Mutable v) f s a))) -> t (Array v f a) -- | O(n) Construct an array of the given shape by filling each position -- with the monadic value. replicateM :: (Monad m, Shape f, Vector v a) => Layout f -> m a -> m (Array v f a) -- | O(n) Construct an array of the given shape by applying the monadic -- function to each index. generateM :: (Monad m, Shape f, Vector v a) => Layout f -> (f Int -> m a) -> m (Array v f a) -- | O(n) Construct an array of the given shape by applying the monadic -- function to each index. linearGenerateM :: (Monad m, Shape f, Vector v a) => Layout f -> (Int -> m a) -> m (Array v f a) -- | The empty Array with a zero shape. empty :: (Vector v a, Additive f) => Array v f a -- | Test is if the array is empty. null :: Foldable f => Array v f a -> Bool -- | Index an element of an array. Throws IndexOutOfBounds if the -- index is out of bounds. (!) :: (Shape f, Vector v a) => Array v f a -> f Int -> a -- | Safe index of an element. (!?) :: (Shape f, Vector v a) => Array v f a -> f Int -> Maybe a -- | Index an element of an array without bounds checking. unsafeIndex :: (Shape f, Vector v a) => Array v f a -> f Int -> a -- | Index an element of an array while ignoring its shape. linearIndex :: Vector v a => Array v f a -> Int -> a -- | Index an element of an array while ignoring its shape, without bounds -- checking. unsafeLinearIndex :: Vector v a => Array v f a -> Int -> a -- | O(1) Indexing in a monad. -- -- The monad allows operations to be strict in the vector when necessary. -- Suppose vector copying is implemented like this: -- --
--   copy mv v = ... write mv i (v ! i) ...
--   
-- -- For lazy vectors, v ! i would not be evaluated which means -- that mv would unnecessarily retain a reference to v -- in each element written. -- -- With indexM, copying can be implemented like this instead: -- --
--   copy mv v = ... do
--     x <- indexM v i
--     write mv i x
--   
-- -- Here, no references to v are retained because indexing (but -- not the elements) is evaluated eagerly. -- -- Throws an error if the index is out of range. indexM :: (Shape f, Vector v a, Monad m) => Array v f a -> f Int -> m a -- | O(1) Indexing in a monad without bounds checks. See -- indexM for an explanation of why this is useful. unsafeIndexM :: (Shape f, Vector v a, Monad m) => Array v f a -> f Int -> m a -- | O(1) Indexing in a monad. Throws an error if the index is out -- of range. linearIndexM :: (Shape f, Vector v a, Monad m) => Array v f a -> Int -> m a -- | O(1) Indexing in a monad without bounds checks. See -- indexM for an explanation of why this is useful. unsafeLinearIndexM :: (Vector v a, Monad m) => Array v f a -> Int -> m a -- | For each pair (i,a) from the list, replace the array element at -- position i by a. (//) :: (Vector v a, Shape f) => Array v f a -> [(f Int, a)] -> Array v f a -- | O(m+n) For each pair (i,b) from the list, replace the -- array element a at position i by f a b. accum :: (Shape f, Vector v a) => (a -> b -> a) -> Array v f a -> [(f Int, b)] -> Array v f a -- | O(n) Map a function over an array map :: (Vector v a, Vector v b) => (a -> b) -> Array v f a -> Array v f b -- | O(n) Apply a function to every element of a vector and its -- index imap :: (Shape f, Vector v a, Vector v b) => (f Int -> a -> b) -> Array v f a -> Array v f b -- | Zip two arrays element wise. If the array's don't have the same shape, -- the new array with be the intersection of the two shapes. zip :: (Shape f, Vector v a, Vector v b, Vector v (a, b)) => Array v f a -> Array v f b -> Array v f (a, b) -- | Zip three arrays element wise. If the array's don't have the same -- shape, the new array with be the intersection of the two shapes. zip3 :: (Shape f, Vector v a, Vector v b, Vector v c, Vector v (a, b, c)) => Array v f a -> Array v f b -> Array v f c -> Array v f (a, b, c) -- | Zip two arrays using the given function. If the array's don't have the -- same shape, the new array with be the intersection of the two shapes. zipWith :: (Shape f, Vector v a, Vector v b, Vector v c) => (a -> b -> c) -> Array v f a -> Array v f b -> Array v f c -- | Zip three arrays using the given function. If the array's don't have -- the same shape, the new array with be the intersection of the two -- shapes. zipWith3 :: (Shape f, Vector v a, Vector v b, Vector v c, Vector v d) => (a -> b -> c -> d) -> Array v f a -> Array v f b -> Array v f c -> Array v f d -- | Zip two arrays using the given function with access to the index. If -- the array's don't have the same shape, the new array with be the -- intersection of the two shapes. izipWith :: (Shape f, Vector v a, Vector v b, Vector v c) => (f Int -> a -> b -> c) -> Array v f a -> Array v f b -> Array v f c -- | Zip two arrays using the given function with access to the index. If -- the array's don't have the same shape, the new array with be the -- intersection of the two shapes. izipWith3 :: (Shape f, Vector v a, Vector v b, Vector v c, Vector v d) => (f Int -> a -> b -> c -> d) -> Array v f a -> Array v f b -> Array v f c -> Array v f d -- | Affine traversal over a single row in a matrix. -- --
--   >>> traverseOf_ rows print $ m & ixRow 1 . each *~ 2
--   [a,b,c,d]
--   [e * 2,f * 2,g * 2,h * 2]
--   [i,j,k,l]
--   
-- -- The row vector should remain the same size to satisfy traversal laws -- but give reasonable behaviour if the size differs: -- --
--   >>> traverseOf_ rows print $ m & ixRow 1 .~ B.fromList [0,1]
--   [a,b,c,d]
--   [0,1,g,h]
--   [i,j,k,l]
--   
-- --
--   >>> traverseOf_ rows print $ m & ixRow 1 .~ B.fromList [0..100]
--   [a,b,c,d]
--   [0,1,2,3]
--   [i,j,k,l]
--   
ixRow :: Vector v a => Int -> IndexedTraversal' Int (Array v V2 a) (v a) -- | Indexed traversal over the rows of a matrix. Each row is an efficient -- slice of the original vector. -- --
--   >>> traverseOf_ rows print m
--   [a,b,c,d]
--   [e,f,g,h]
--   [i,j,k,l]
--   
rows :: (Vector v a, Vector w b) => IndexedTraversal Int (Array v V2 a) (Array w V2 b) (v a) (w b) -- | Affine traversal over a single column in a matrix. -- --
--   >>> traverseOf_ rows print $ m & ixColumn 2 . each +~ 1
--   [a,b,c + 1,d]
--   [e,f,g + 1,h]
--   [i,j,k + 1,l]
--   
ixColumn :: Vector v a => Int -> IndexedTraversal' Int (Array v V2 a) (v a) -- | Indexed traversal over the columns of a matrix. Unlike rows, -- each column is a new separate vector. -- --
--   >>> traverseOf_ columns print m
--   [a,e,i]
--   [b,f,j]
--   [c,g,k]
--   [d,h,l]
--   
-- --
--   >>> traverseOf_ rows print $ m & columns . indices odd . each .~ 0
--   [a,0,c,0]
--   [e,0,g,0]
--   [i,0,k,0]
--   
-- -- The vectors should be the same size to be a valid traversal. If the -- vectors are different sizes, the number of rows in the new array will -- be the length of the smallest vector. columns :: (Vector v a, Vector w b) => IndexedTraversal Int (Array v V2 a) (Array w V2 b) (v a) (w b) -- | Traversal over a single plane of a 3D array given a lens onto that -- plane (like _xy, _yz, _zx). ixPlane :: Vector v a => ALens' (V3 Int) (V2 Int) -> Int -> IndexedTraversal' Int (Array v V3 a) (Array v V2 a) -- | Traversal over all planes of 3D array given a lens onto that plane -- (like _xy, _yz, _zx). planes :: (Vector v a, Vector w b) => ALens' (V3 Int) (V2 Int) -> IndexedTraversal Int (Array v V3 a) (Array w V3 b) (Array v V2 a) (Array w V2 b) -- | Flatten a plane by reducing a vector in the third dimension to a -- single value. flattenPlane :: (Vector v a, Vector w b) => ALens' (V3 Int) (V2 Int) -> (v a -> b) -> Array v V3 a -> Array w V2 b -- | This Traversal should not have any duplicates in the list of -- indices. unsafeOrdinals :: (Vector v a, Shape f) => [f Int] -> IndexedTraversal' (f Int) (Array v f a) a -- | A mutable array with a shape. data MArray v l s a -- | Boxed mutable array. type BMArray = MArray MVector -- | Unboxed mutable array. type UMArray = MArray MVector -- | Storable mutable array. type SMArray = MArray MVector -- | Primitive mutable array. type PMArray = MArray MVector -- | O(n) Yield an immutable copy of the mutable array. thaw :: (PrimMonad m, Vector v a) => Array v f a -> m (MArray (Mutable v) f (PrimState m) a) -- | O(n) Yield a mutable copy of the immutable vector. freeze :: (PrimMonad m, Vector v a) => MArray (Mutable v) f (PrimState m) a -> m (Array v f a) -- | O(1) Unsafely convert an immutable array to a mutable one without -- copying. The immutable array may not be used after this operation. unsafeThaw :: (PrimMonad m, Vector v a) => Array v f a -> m (MArray (Mutable v) f (PrimState m) a) -- | O(1) Unsafe convert a mutable array to an immutable one without -- copying. The mutable array may not be used after this operation. unsafeFreeze :: (PrimMonad m, Vector v a) => MArray (Mutable v) f (PrimState m) a -> m (Array v f a) -- | A delayed representation of an array. This useful for mapping over an -- array in parallel. data Delayed f a -- | Isomorphism between an array and its delayed representation. -- Conversion to the array is done in parallel. delayed :: (Vector v a, Vector w b, Shape f, Shape g) => Iso (Array v f a) (Array w g b) (Delayed f a) (Delayed g b) -- | Isomorphism between an array and its delayed representation. -- Conversion to the array is done in parallel. seqDelayed :: (Vector v a, Vector w b, Shape f, Shape g) => Iso (Array v f a) (Array w g b) (Delayed f a) (Delayed g b) -- | Turn a material array into a delayed one with the same shape. delay :: (Vector v a, Shape f) => Array v f a -> Delayed f a -- | Parallel manifestation of a delayed array into a material one. manifest :: (Vector v a, Shape f) => Delayed f a -> Array v f a -- | Sequential manifestation of a delayed array. seqManifest :: (Vector v a, Shape f) => Delayed f a -> Array v f a -- | Generate a Delayed array using the given Layout and -- construction function. genDelayed :: Layout f -> (f Int -> a) -> Delayed f a -- | Index a delayed array, returning a IndexOutOfBounds exception -- if the index is out of range. indexDelayed :: Shape f => Delayed f a -> f Int -> a -- | manifest an array to a UArray and delay again. See -- Data.Dense.Boxed or Data.Dense.Storable to affirm -- for other types of arrays. affirm :: (Shape f, Unbox a) => Delayed f a -> Delayed f a -- | seqManifest an array to a UArray and delay again. See -- Data.Dense.Boxed or Data.Dense.Storable to affirm -- for other types of arrays. seqAffirm :: (Shape f, Unbox a) => Delayed f a -> Delayed f a -- | A delayed representation of an array with a focus on a single element. -- This element is the target of extract. data Focused f a -- | Focus on a particular element of a delayed array. focusOn :: f Int -> Delayed f a -> Focused f a -- | Discard the focus to retrieve the delayed array. unfocus :: Focused f a -> Delayed f a -- | Indexed lens onto the delayed array, indexed at the focus. unfocused :: IndexedLens (f Int) (Focused f a) (Focused f b) (Delayed f a) (Delayed f b) -- | Modify a Delayed array by extracting a value from a -- Focused each point. extendFocus :: Shape f => (Focused f a -> b) -> Delayed f a -> Delayed f b -- | Lens onto the position of a ComonadStore. -- --
--   locale :: Lens' (Focused l a) (l Int)
--   
locale :: ComonadStore s w => Lens' (w a) s -- | Focus on a neighbouring element, relative to the current focus. shiftFocus :: Applicative f => f Int -> Focused f a -> Focused f a -- | The boundary condition used for indexing relative elements in a -- Focused. data Boundary -- | clamp coordinates to the extent of the array Clamp :: Boundary -- | mirror coordinates beyond the array extent Mirror :: Boundary -- | wrap coordinates around on each dimension Wrap :: Boundary -- | Index a focused using a Boundary condition. peekB :: Shape f => Boundary -> f Int -> Focused f a -> a -- | Index an element by applying a function the current position, using a -- boundary condition. peeksB :: Shape f => Boundary -> (f Int -> f Int) -> Focused f a -> a -- | Index an element relative to the current focus using a Boundary -- condition. peekRelativeB :: Shape f => Boundary -> f Int -> Focused f a -> a -- | Generate a stream from a Layout's indices. streamGenerate :: (Monad m, Shape f) => Layout f -> (f Int -> a) -> Stream m a -- | Generate a stream from a Layout's indices. streamGenerateM :: (Monad m, Shape f) => Layout f -> (f Int -> m a) -> Stream m a -- | Make a stream of the indexes of a Layout. streamIndexes :: (Monad m, Shape f) => Layout f -> Stream m (f Int) -- | Generate a bundle from Layout indices. bundleGenerate :: (Monad m, Shape f) => Layout f -> (f Int -> a) -> MBundle m v a -- | Generate a bundle from Layout indices. bundleGenerateM :: (Monad m, Shape f) => Layout f -> (f Int -> m a) -> MBundle m v a -- | Generate a bundle of indexes for the given Layout. bundleIndexes :: (Monad m, Shape f) => Layout f -> MBundle m v (f Int) instance GHC.Read.Read Data.Dense.Generic.Boundary instance GHC.Show.Show Data.Dense.Generic.Boundary -- | Boxed multidimensional arrays. module Data.Dense.Boxed -- | Boxed array. type BArray = Array Vector -- | Class for types that can be converted to and from linear indexes. class (Eq1 f, Additive f, Traversable f) => Shape f -- | Class of things that have a Layout. This means we can use the -- same functions for the various different arrays in the library. class Shape f => HasLayout f a | a -> f -- | Lens onto the Layout of something. layout :: HasLayout f a => Lens' a (Layout f) -- | Lens onto the Layout of something. layout :: (HasLayout f a, a ~ f Int) => (Layout f -> g (Layout f)) -> a -> g a -- | A Layout is the full size of an array. This alias is used to -- help distinguish between the layout of an array and an index (usually -- just l Int) in a type signature. type Layout f = f Int -- | Get the extent of an array. -- --
--   extent :: Array v f a    -> f Int
--   extent :: MArray v f s a -> f Int
--   extent :: Delayed f a    -> f Int
--   extent :: Focused f a    -> f Int
--   
extent :: HasLayout f a => a -> f Int -- | Get the total number of elements in an array. -- --
--   size :: Array v f a    -> Int
--   size :: MArray v f s a -> Int
--   size :: Delayed f a    -> Int
--   size :: Focused f a    -> Int
--   
size :: HasLayout f a => a -> Int -- | Indexed fold for all the indexes in the layout. indexes :: HasLayout f a => IndexedFold Int a (f Int) -- | Indexed fold starting starting from some point, where the index is the -- linear index for the original layout. indexesFrom :: HasLayout f a => f Int -> IndexedFold Int a (f Int) -- | Indexed fold between the two indexes where the index is the linear -- index for the original layout. indexesBetween :: HasLayout f a => f Int -> f Int -> IndexedFold Int a (f Int) -- | Indexed lens over the underlying vector of an array. The index is the -- extent of the array. You must _not_ change the length of the -- vector, otherwise an error will be thrown (even for V1 layouts, -- use flat for V1). vector :: IndexedLens (Layout f) (BArray f a) (BArray f b) (Vector a) (Vector b) -- | Same as values but restrictive in the vector type. values :: Shape f => IndexedTraversal (f Int) (BArray f a) (BArray f b) a b -- | Same as values but restrictive in the vector type. values' :: Shape f => IndexedTraversal (f Int) (BArray f a) (BArray f b) a b -- | Same as values but restrictive in the vector type. valuesBetween :: Shape f => f Int -> f Int -> IndexedTraversal' (f Int) (BArray f a) a -- | 1D arrays are just vectors. You are free to change the length of the -- vector when going over this Iso (unlike -- linear). -- -- Note that V1 arrays are an instance of Vector so you can -- use any of the functions in Generic on them without needing to -- convert. flat :: Iso (BArray V1 a) (BArray V1 b) (Vector a) (Vector b) -- | Contruct a flat array from a list. (This is just fromList from -- Generic.) fromList :: [a] -> BArray V1 a -- | O(n) Convert the first n elements of a list to an BArrayith -- the given shape. Returns Nothing if there are not enough -- elements in the list. fromListInto :: Shape f => Layout f -> [a] -> Maybe (BArray f a) -- | O(n) Convert the first n elements of a list to an BArrayith -- the given shape. Throw an error if the list is not long enough. fromListInto_ :: Shape f => Layout f -> [a] -> BArray f a -- | Create an array from a vector and a layout. Return -- Nothing if the vector is not the right shape. fromVectorInto :: Shape f => Layout f -> Vector a -> Maybe (BArray f a) -- | Create an array from a vector and a layout. Throws an -- error if the vector is not the right shape. fromVectorInto_ :: Shape f => Layout f -> Vector a -> BArray f a -- | O(n) BArray of the given shape with the same value in each position. replicate :: Shape f => f Int -> a -> BArray f a -- | O(n) Construct an array of the given shape by applying the function to -- each index. generate :: Shape f => Layout f -> (f Int -> a) -> BArray f a -- | O(n) Construct an array of the given shape by applying the function to -- each index. linearGenerate :: Shape f => Layout f -> (Int -> a) -> BArray f a -- | Execute the monadic action and freeze the resulting array. create :: (forall s. ST s (BMArray f s a)) -> BArray f a -- | O(n) Construct an array of the given shape by filling each position -- with the monadic value. replicateM :: (Monad m, Shape f) => Layout f -> m a -> m (BArray f a) -- | O(n) Construct an array of the given shape by applying the monadic -- function to each index. generateM :: (Monad m, Shape f) => Layout f -> (f Int -> m a) -> m (BArray f a) -- | O(n) Construct an array of the given shape by applying the monadic -- function to each index. linearGenerateM :: (Monad m, Shape f) => Layout f -> (Int -> m a) -> m (BArray f a) -- | The empty BArray with a zero shape. empty :: Additive f => BArray f a -- | Test is if the array is empty. null :: Foldable f => BArray f a -> Bool -- | Index an element of an array. Throws IndexOutOfBounds if the -- index is out of bounds. (!) :: Shape f => BArray f a -> f Int -> a -- | Safe index of an element. (!?) :: Shape f => BArray f a -> f Int -> Maybe a -- | Index an element of an array without bounds checking. unsafeIndex :: Shape f => BArray f a -> f Int -> a -- | Index an element of an array while ignoring its shape. linearIndex :: BArray f a -> Int -> a -- | Index an element of an array while ignoring its shape, without bounds -- checking. unsafeLinearIndex :: BArray f a -> Int -> a -- | O(1) Indexing in a monad. -- -- The monad allows operations to be strict in the vector when necessary. -- Suppose vector copying is implemented like this: -- --
--   copy mv v = ... write mv i (v ! i) ...
--   
-- -- For lazy vectors, v ! i would not be evaluated which means -- that mv would unnecessarily retain a reference to v -- in each element written. -- -- With indexM, copying can be implemented like this instead: -- --
--   copy mv v = ... do
--     x <- indexM v i
--     write mv i x
--   
-- -- Here, no references to v are retained because indexing (but -- not the elements) is evaluated eagerly. -- -- Throws an error if the index is out of range. indexM :: (Shape f, Monad m) => BArray f a -> f Int -> m a -- | O(1) Indexing in a monad without bounds checks. See -- indexM for an explanation of why this is useful. unsafeIndexM :: (Shape f, Monad m) => BArray f a -> f Int -> m a -- | O(1) Indexing in a monad. Throws an error if the index is out -- of range. linearIndexM :: (Shape f, Monad m) => BArray f a -> Int -> m a -- | O(1) Indexing in a monad without bounds checks. See -- indexM for an explanation of why this is useful. unsafeLinearIndexM :: Monad m => BArray f a -> Int -> m a -- | For each pair (i,a) from the list, replace the array element at -- position i by a. (//) :: Shape f => BArray f a -> [(f Int, a)] -> BArray f a -- | O(m+n) For each pair (i,b) from the list, replace the -- array element a at position i by f a b. accum :: Shape f => (a -> b -> a) -> BArray f a -> [(f Int, b)] -> BArray f a -- | O(n) Map a function over an array map :: (a -> b) -> BArray f a -> BArray f b -- | O(n) Apply a function to every element of a vector and its -- index imap :: Shape f => (f Int -> a -> b) -> BArray f a -> BArray f b -- | Zip two arrays element wise. If the array's don't have the same shape, -- the new array with be the intersection of the two shapes. zip :: Shape f => BArray f a -> BArray f b -> BArray f (a, b) -- | Zip three arrays element wise. If the array's don't have the same -- shape, the new array with be the intersection of the two shapes. zip3 :: Shape f => BArray f a -> BArray f b -> BArray f c -> BArray f (a, b, c) -- | Zip two arrays using the given function. If the array's don't have the -- same shape, the new array with be the intersection of the two shapes. zipWith :: Shape f => (a -> b -> c) -> BArray f a -> BArray f b -> BArray f c -- | Zip three arrays using the given function. If the array's don't have -- the same shape, the new array with be the intersection of the two -- shapes. zipWith3 :: Shape f => (a -> b -> c -> d) -> BArray f a -> BArray f b -> BArray f c -> BArray f d -- | Zip two arrays using the given function with access to the index. If -- the array's don't have the same shape, the new array with be the -- intersection of the two shapes. izipWith :: Shape f => (f Int -> a -> b -> c) -> BArray f a -> BArray f b -> BArray f c -- | Zip two arrays using the given function with access to the index. If -- the array's don't have the same shape, the new array with be the -- intersection of the two shapes. izipWith3 :: Shape f => (f Int -> a -> b -> c -> d) -> BArray f a -> BArray f b -> BArray f c -> BArray f d -- | Affine traversal over a single row in a matrix. -- --
--   >>> traverseOf_ rows print $ m & ixRow 1 . each *~ 2
--   [a,b,c,d]
--   [e * 2,f * 2,g * 2,h * 2]
--   [i,j,k,l]
--   
-- -- The row vector should remain the same size to satisfy traversal laws -- but give reasonable behaviour if the size differs: -- --
--   >>> traverseOf_ rows print $ m & ixRow 1 .~ V.fromList [0,1]
--   [a,b,c,d]
--   [0,1,g,h]
--   [i,j,k,l]
--   
-- --
--   >>> traverseOf_ rows print $ m & ixRow 1 .~ V.fromList [0..100]
--   [a,b,c,d]
--   [0,1,2,3]
--   [i,j,k,l]
--   
ixRow :: Int -> IndexedTraversal' Int (BArray V2 a) (Vector a) -- | Indexed traversal over the rows of a matrix. Each row is an efficient -- slice of the original vector. -- --
--   >>> traverseOf_ rows print m
--   [a,b,c,d]
--   [e,f,g,h]
--   [i,j,k,l]
--   
rows :: IndexedTraversal Int (BArray V2 a) (BArray V2 b) (Vector a) (Vector b) -- | Affine traversal over a single column in a matrix. -- --
--   >>> traverseOf_ rows print $ m & ixColumn 2 . each +~ 1
--   [a,b,c + 1,d]
--   [e,f,g + 1,h]
--   [i,j,k + 1,l]
--   
ixColumn :: Int -> IndexedTraversal' Int (BArray V2 a) (Vector a) -- | Indexed traversal over the columns of a matrix. Unlike rows, -- each column is a new separate vector. -- --
--   >>> traverseOf_ columns print m
--   [a,e,i]
--   [b,f,j]
--   [c,g,k]
--   [d,h,l]
--   
-- --
--   >>> traverseOf_ rows print $ m & columns . indices odd . each .~ 0
--   [a,0,c,0]
--   [e,0,g,0]
--   [i,0,k,0]
--   
-- -- The vectors should be the same size to be a valid traversal. If the -- vectors are different sizes, the number of rows in the new array will -- be the length of the smallest vector. columns :: IndexedTraversal Int (BArray V2 a) (BArray V2 b) (Vector a) (Vector b) -- | Traversal over a single plane of a 3D array given a lens onto that -- plane (like _xy, _yz, _zx). ixPlane :: ALens' (V3 Int) (V2 Int) -> Int -> IndexedTraversal' Int (BArray V3 a) (BArray V2 a) -- | Traversal over all planes of 3D array given a lens onto that plane -- (like _xy, _yz, _zx). planes :: ALens' (V3 Int) (V2 Int) -> IndexedTraversal Int (BArray V3 a) (BArray V3 b) (BArray V2 a) (BArray V2 b) -- | Flatten a plane by reducing a vector in the third dimension to a -- single value. flattenPlane :: ALens' (V3 Int) (V2 Int) -> (Vector a -> b) -> BArray V3 a -> BArray V2 b -- | This Traversal should not have any duplicates in the list of -- indices. unsafeOrdinals :: Shape f => [f Int] -> IndexedTraversal' (f Int) (BArray f a) a -- | Boxed mutable array. type BMArray = MArray MVector -- | O(n) Yield an immutable copy of the mutable array. thaw :: PrimMonad m => BArray f a -> m (BMArray f (PrimState m) a) -- | O(n) Yield a mutable copy of the immutable vector. freeze :: PrimMonad m => BMArray f (PrimState m) a -> m (BArray f a) -- | O(1) Unsafely convert an immutable array to a mutable one without -- copying. The immutable array may not be used after this operation. unsafeThaw :: PrimMonad m => BArray f a -> m (BMArray f (PrimState m) a) -- | O(1) Unsafe convert a mutable array to an immutable one without -- copying. The mutable array may not be used after this operation. unsafeFreeze :: PrimMonad m => BMArray f (PrimState m) a -> m (BArray f a) -- | A delayed representation of an array. This useful for mapping over an -- array in parallel. data Delayed f a -- | Isomorphism between an array and its delayed representation. -- Conversion to the array is done in parallel. delayed :: (Shape f, Shape k) => Iso (BArray f a) (BArray k b) (Delayed f a) (Delayed k b) -- | Isomorphism between an array and its delayed representation. -- Conversion to the array is done in sequence. seqDelayed :: (Shape f, Shape k) => Iso (BArray f a) (BArray k b) (Delayed f a) (Delayed k b) -- | Turn a material array into a delayed one with the same shape. delay :: Shape f => BArray f a -> Delayed f a -- | Parallel manifestation of a delayed array into a material one. manifest :: Shape f => Delayed f a -> BArray f a -- | Sequential manifestation of a delayed array. seqManifest :: Shape f => Delayed f a -> BArray f a -- | Generate a Delayed array using the given Layout and -- construction function. genDelayed :: Layout f -> (f Int -> a) -> Delayed f a -- | Index a delayed array, returning a IndexOutOfBounds exception -- if the index is out of range. indexDelayed :: Shape f => Delayed f a -> f Int -> a -- | manifest an array to a BArray and delay again. affirm :: Shape f => Delayed f a -> Delayed f a -- | seqManifest an array to a BArray and delay again. seqAffirm :: Shape f => Delayed f a -> Delayed f a -- | A delayed representation of an array with a focus on a single element. -- This element is the target of extract. data Focused f a -- | Focus on a particular element of a delayed array. focusOn :: f Int -> Delayed f a -> Focused f a -- | Discard the focus to retrieve the delayed array. unfocus :: Focused f a -> Delayed f a -- | Indexed lens onto the delayed array, indexed at the focus. unfocused :: IndexedLens (f Int) (Focused f a) (Focused f b) (Delayed f a) (Delayed f b) -- | Modify a Delayed array by extracting a value from a -- Focused each point. extendFocus :: Shape f => (Focused f a -> b) -> Delayed f a -> Delayed f b -- | Lens onto the position of a ComonadStore. -- --
--   locale :: Lens' (Focused l a) (l Int)
--   
locale :: ComonadStore s w => Lens' (w a) s -- | Focus on a neighbouring element, relative to the current focus. shiftFocus :: Applicative f => f Int -> Focused f a -> Focused f a -- | Stencils can be used to sum (or any fold) over neighbouring sites to -- the current position on a Focused. module Data.Dense.Stencil -- | Stencils are used to fold over neighbouring array sites. To construct -- a stencil use mkStencil, mkStencilUnboxed. For static -- sized stencils you can use the quasiquoter stencil. -- -- To use a stencil you can use stencilSum or use the -- Foldable and FoldableWithIndex instances. newtype Stencil f a Stencil :: (forall b. (f Int -> a -> b -> b) -> b -> b) -> Stencil f a -- | Make a stencil folding over a list. -- -- If the list is staticlly known this should expand at compile time via -- rewrite rules, similar to makeStencilTH but less reliable. If -- that does not happen the resulting could be slow. If the list is not -- know at compile time, mkStencilUnboxed can be signifcantly -- faster (but isn't subject expending via rewrite rules). mkStencil :: [(f Int, a)] -> Stencil f a -- | Make a stencil folding over an unboxed vector from the list. mkStencilUnboxed :: (Unbox (f Int), Unbox a) => [(f Int, a)] -> Stencil f a -- | Sum the elements around a Focused using a Boundary -- condition and a Stencil. -- -- This is often used in conjunction with extendFocus. stencilSum :: (Shape f, Num a) => Boundary -> Stencil f a -> Focused f a -> a instance (Data.Functor.Classes.Show1 f, GHC.Show.Show a) => GHC.Show.Show (Data.Dense.Stencil.Stencil f a) instance Data.Foldable.Foldable (Data.Dense.Stencil.Stencil f) instance Control.Lens.Indexed.FoldableWithIndex (f GHC.Types.Int) (Data.Dense.Stencil.Stencil f) instance GHC.Base.Functor (Data.Dense.Stencil.Stencil f) -- | Storeable multidimentional arrays. module Data.Dense.Storable -- | Storeable array. type SArray = Array Vector -- | The member functions of this class facilitate writing values of -- primitive types to raw memory (which may have been allocated with the -- above mentioned routines) and reading values from blocks of raw -- memory. The class, furthermore, includes support for computing the -- storage requirements and alignment restrictions of storable types. -- -- Memory addresses are represented as values of type Ptr -- a, for some a which is an instance of class -- Storable. The type argument to Ptr helps provide some -- valuable type safety in FFI code (you can't mix pointers of different -- types without an explicit cast), while helping the Haskell type system -- figure out which marshalling method is needed for a given pointer. -- -- All marshalling between Haskell and a foreign language ultimately -- boils down to translating Haskell data structures into the binary -- representation of a corresponding data structure of the foreign -- language and vice versa. To code this marshalling in Haskell, it is -- necessary to manipulate primitive data types stored in unstructured -- memory blocks. The class Storable facilitates this manipulation -- on all types for which it is instantiated, which are the standard -- basic types of Haskell, the fixed size Int types -- (Int8, Int16, Int32, Int64), the fixed -- size Word types (Word8, Word16, Word32, -- Word64), StablePtr, all types from -- Foreign.C.Types, as well as Ptr. class Storable a -- | Class for types that can be converted to and from linear indexes. class (Eq1 f, Additive f, Traversable f) => Shape f -- | Class of things that have a Layout. This means we can use the -- same functions for the various different arrays in the library. class Shape f => HasLayout f a | a -> f -- | Lens onto the Layout of something. layout :: HasLayout f a => Lens' a (Layout f) -- | Lens onto the Layout of something. layout :: (HasLayout f a, a ~ f Int) => (Layout f -> g (Layout f)) -> a -> g a -- | A Layout is the full size of an array. This alias is used to -- help distinguish between the layout of an array and an index (usually -- just l Int) in a type signature. type Layout f = f Int -- | Get the extent of an array. -- --
--   extent :: Array v f a    -> f Int
--   extent :: MArray v f s a -> f Int
--   extent :: Delayed f a    -> f Int
--   extent :: Focused f a    -> f Int
--   
extent :: HasLayout f a => a -> f Int -- | Get the total number of elements in an array. -- --
--   size :: Array v f a    -> Int
--   size :: MArray v f s a -> Int
--   size :: Delayed f a    -> Int
--   size :: Focused f a    -> Int
--   
size :: HasLayout f a => a -> Int -- | Indexed fold for all the indexes in the layout. indexes :: HasLayout f a => IndexedFold Int a (f Int) -- | Indexed fold starting starting from some point, where the index is the -- linear index for the original layout. indexesFrom :: HasLayout f a => f Int -> IndexedFold Int a (f Int) -- | Indexed fold between the two indexes where the index is the linear -- index for the original layout. indexesBetween :: HasLayout f a => f Int -> f Int -> IndexedFold Int a (f Int) -- | Indexed lens over the underlying vector of an array. The index is the -- extent of the array. You must _not_ change the length of the -- vector, otherwise an error will be thrown (even for V1 layouts, -- use flat for V1). vector :: (Storable a, Storable b) => IndexedLens (Layout f) (SArray f a) (SArray f b) (Vector a) (Vector b) -- | Same as values but restrictive in the vector type. values :: (Shape f, Storable a, Storable b) => IndexedTraversal (f Int) (SArray f a) (SArray f b) a b -- | Same as values but restrictive in the vector type. values' :: (Shape f, Storable a, Storable b) => IndexedTraversal (f Int) (SArray f a) (SArray f b) a b -- | Same as values but restrictive in the vector type. valuesBetween :: (Shape f, Storable a) => f Int -> f Int -> IndexedTraversal' (f Int) (SArray f a) a -- | 1D arrays are just vectors. You are free to change the length of the -- vector when going over this Iso (unlike -- linear). -- -- Note that V1 arrays are an instance of Vector so you can -- use any of the functions in Generic on them without needing to -- convert. flat :: Storable b => Iso (SArray V1 a) (SArray V1 b) (Vector a) (Vector b) -- | Contruct a flat array from a list. (This is just fromList from -- Generic.) fromList :: Storable a => [a] -> SArray V1 a -- | O(n) Convert the first n elements of a list to an SArrayith -- the given shape. Returns Nothing if there are not enough -- elements in the list. fromListInto :: (Shape f, Storable a) => Layout f -> [a] -> Maybe (SArray f a) -- | O(n) Convert the first n elements of a list to an SArrayith -- the given shape. Throw an error if the list is not long enough. fromListInto_ :: (Shape f, Storable a) => Layout f -> [a] -> SArray f a -- | Create an array from a vector and a layout. Return -- Nothing if the vector is not the right shape. fromVectorInto :: (Shape f, Storable a) => Layout f -> Vector a -> Maybe (SArray f a) -- | Create an array from a vector and a layout. Throws an -- error if the vector is not the right shape. fromVectorInto_ :: (Shape f, Storable a) => Layout f -> Vector a -> SArray f a -- | O(n) SArray of the given shape with the same value in each position. replicate :: (Shape f, Storable a) => f Int -> a -> SArray f a -- | O(n) Construct an array of the given shape by applying the function to -- each index. generate :: (Shape f, Storable a) => Layout f -> (f Int -> a) -> SArray f a -- | O(n) Construct an array of the given shape by applying the function to -- each index. linearGenerate :: (Shape f, Storable a) => Layout f -> (Int -> a) -> SArray f a -- | Execute the monadic action and freeze the resulting array. create :: Storable a => (forall s. ST s (SMArray f s a)) -> SArray f a -- | O(n) Construct an array of the given shape by filling each position -- with the monadic value. replicateM :: (Monad m, Shape f, Storable a) => Layout f -> m a -> m (SArray f a) -- | O(n) Construct an array of the given shape by applying the monadic -- function to each index. generateM :: (Monad m, Shape f, Storable a) => Layout f -> (f Int -> m a) -> m (SArray f a) -- | O(n) Construct an array of the given shape by applying the monadic -- function to each index. linearGenerateM :: (Monad m, Shape f, Storable a) => Layout f -> (Int -> m a) -> m (SArray f a) -- | The empty SArray with a zero shape. empty :: (Storable a, Additive f) => SArray f a -- | Test is if the array is empty. null :: Foldable f => SArray f a -> Bool -- | Index an element of an array. Throws IndexOutOfBounds if the -- index is out of bounds. (!) :: (Shape f, Storable a) => SArray f a -> f Int -> a -- | Safe index of an element. (!?) :: (Shape f, Storable a) => SArray f a -> f Int -> Maybe a -- | Index an element of an array without bounds checking. unsafeIndex :: (Shape f, Storable a) => SArray f a -> f Int -> a -- | Index an element of an array while ignoring its shape. linearIndex :: Storable a => SArray f a -> Int -> a -- | Index an element of an array while ignoring its shape, without bounds -- checking. unsafeLinearIndex :: Storable a => SArray f a -> Int -> a -- | O(1) Indexing in a monad. -- -- The monad allows operations to be strict in the vector when necessary. -- Suppose vector copying is implemented like this: -- --
--   copy mv v = ... write mv i (v ! i) ...
--   
-- -- For lazy vectors, v ! i would not be evaluated which means -- that mv would unnecessarily retain a reference to v -- in each element written. -- -- With indexM, copying can be implemented like this instead: -- --
--   copy mv v = ... do
--     x <- indexM v i
--     write mv i x
--   
-- -- Here, no references to v are retained because indexing (but -- not the elements) is evaluated eagerly. -- -- Throws an error if the index is out of range. indexM :: (Shape f, Storable a, Monad m) => SArray f a -> f Int -> m a -- | O(1) Indexing in a monad without bounds checks. See -- indexM for an explanation of why this is useful. unsafeIndexM :: (Shape f, Storable a, Monad m) => SArray f a -> f Int -> m a -- | O(1) Indexing in a monad. Throws an error if the index is out -- of range. linearIndexM :: (Shape f, Storable a, Monad m) => SArray f a -> Int -> m a -- | O(1) Indexing in a monad without bounds checks. See -- indexM for an explanation of why this is useful. unsafeLinearIndexM :: (Storable a, Monad m) => SArray f a -> Int -> m a -- | For each pair (i,a) from the list, replace the array element at -- position i by a. (//) :: (Storable a, Shape f) => SArray f a -> [(f Int, a)] -> SArray f a -- | O(m+n) For each pair (i,b) from the list, replace the -- array element a at position i by f a b. accum :: (Shape f, Storable a) => (a -> b -> a) -> SArray f a -> [(f Int, b)] -> SArray f a -- | O(n) Map a function over an array map :: (Storable a, Storable b) => (a -> b) -> SArray f a -> SArray f b -- | O(n) Apply a function to every element of a vector and its -- index imap :: (Shape f, Storable a, Storable b) => (f Int -> a -> b) -> SArray f a -> SArray f b -- | Zip two arrays using the given function. If the array's don't have the -- same shape, the new array with be the intersection of the two shapes. zipWith :: (Shape f, Storable a, Storable b, Storable c) => (a -> b -> c) -> SArray f a -> SArray f b -> SArray f c -- | Zip three arrays using the given function. If the array's don't have -- the same shape, the new array with be the intersection of the two -- shapes. zipWith3 :: (Shape f, Storable a, Storable b, Storable c, Storable d) => (a -> b -> c -> d) -> SArray f a -> SArray f b -> SArray f c -> SArray f d -- | Zip two arrays using the given function with access to the index. If -- the array's don't have the same shape, the new array with be the -- intersection of the two shapes. izipWith :: (Shape f, Storable a, Storable b, Storable c) => (f Int -> a -> b -> c) -> SArray f a -> SArray f b -> SArray f c -- | Zip two arrays using the given function with access to the index. If -- the array's don't have the same shape, the new array with be the -- intersection of the two shapes. izipWith3 :: (Shape f, Storable a, Storable b, Storable c, Storable d) => (f Int -> a -> b -> c -> d) -> SArray f a -> SArray f b -> SArray f c -> SArray f d -- | Affine traversal over a single row in a matrix. -- --
--   >>> traverseOf_ rows print $ m & ixRow 1 . each +~ 2
--   [1,2,3]
--   [6,7,8]
--   
-- -- The row vector should remain the same size to satisfy traversal laws -- but give reasonable behaviour if the size differs: -- --
--   >>> traverseOf_ rows print $ m & ixRow 1 .~ V.fromList [0,1]
--   [1,2,3]
--   [0,1,6]
--   
-- --
--   >>> traverseOf_ rows print $ m & ixRow 1 .~ V.fromList [0..100]
--   [1,2,3]
--   [0,1,2]
--   
ixRow :: Storable a => Int -> IndexedTraversal' Int (SArray V2 a) (Vector a) -- | Indexed traversal over the rows of a matrix. Each row is an efficient -- slice of the original vector. -- --
--   >>> traverseOf_ rows print m
--   [1,2,3]
--   [4,5,6]
--   
rows :: (Storable a, Storable b) => IndexedTraversal Int (SArray V2 a) (SArray V2 b) (Vector a) (Vector b) -- | Affine traversal over a single column in a matrix. -- --
--   >>> traverseOf_ rows print $ m & ixColumn 2 . each *~ 10
--   [1,2,30]
--   [4,5,60]
--   
ixColumn :: Storable a => Int -> IndexedTraversal' Int (SArray V2 a) (Vector a) -- | Indexed traversal over the columns of a matrix. Unlike rows, -- each column is a new separate vector. -- --
--   >>> traverseOf_ columns print m
--   [1,4]
--   [2,5]
--   [3,6]
--   
-- --
--   >>> traverseOf_ rows print $ m & columns . indices odd . each .~ 0
--   [1,0,3]
--   [4,0,6]
--   
-- -- The vectors should be the same size to be a valid traversal. If the -- vectors are different sizes, the number of rows in the new array will -- be the length of the smallest vector. columns :: (Storable a, Storable b) => IndexedTraversal Int (SArray V2 a) (SArray V2 b) (Vector a) (Vector b) -- | Traversal over a single plane of a 3D array given a lens onto that -- plane (like _xy, _yz, _zx). ixPlane :: Storable a => ALens' (V3 Int) (V2 Int) -> Int -> IndexedTraversal' Int (SArray V3 a) (SArray V2 a) -- | Traversal over all planes of 3D array given a lens onto that plane -- (like _xy, _yz, _zx). planes :: (Storable a, Storable b) => ALens' (V3 Int) (V2 Int) -> IndexedTraversal Int (SArray V3 a) (SArray V3 b) (SArray V2 a) (SArray V2 b) -- | Flatten a plane by reducing a vector in the third dimension to a -- single value. flattenPlane :: (Storable a, Storable b) => ALens' (V3 Int) (V2 Int) -> (Vector a -> b) -> SArray V3 a -> SArray V2 b -- | This Traversal should not have any duplicates in the list of -- indices. unsafeOrdinals :: (Storable a, Shape f) => [f Int] -> IndexedTraversal' (f Int) (SArray f a) a -- | Storable mutable array. type SMArray = MArray MVector -- | O(n) Yield an immutable copy of the mutable array. thaw :: (PrimMonad m, Storable a) => SArray f a -> m (SMArray f (PrimState m) a) -- | O(n) Yield a mutable copy of the immutable vector. freeze :: (PrimMonad m, Storable a) => SMArray f (PrimState m) a -> m (SArray f a) -- | O(1) Unsafely convert an immutable array to a mutable one without -- copying. The immutable array may not be used after this operation. unsafeThaw :: (PrimMonad m, Storable a) => SArray f a -> m (SMArray f (PrimState m) a) -- | O(1) Unsafe convert a mutable array to an immutable one without -- copying. The mutable array may not be used after this operation. unsafeFreeze :: (PrimMonad m, Storable a) => SMArray f (PrimState m) a -> m (SArray f a) -- | A delayed representation of an array. This useful for mapping over an -- array in parallel. data Delayed f a -- | Isomorphism between an array and its delayed representation. -- Conversion to the array is done in parallel. delayed :: (Storable a, Storable b, Shape f, Shape k) => Iso (SArray f a) (SArray k b) (Delayed f a) (Delayed k b) -- | Isomorphism between an array and its delayed representation. -- Conversion to the array is done in sequence. seqDelayed :: (Storable a, Storable b, Shape f, Shape k) => Iso (SArray f a) (SArray k b) (Delayed f a) (Delayed k b) -- | Turn a material array into a delayed one with the same shape. delay :: (Storable a, Shape f) => SArray f a -> Delayed f a -- | Parallel manifestation of a delayed array into a material one. manifest :: (Storable a, Shape f) => Delayed f a -> SArray f a -- | Sequential manifestation of a delayed array. seqManifest :: (Storable a, Shape f) => Delayed f a -> SArray f a -- | Generate a Delayed array using the given Layout and -- construction function. genDelayed :: Layout f -> (f Int -> a) -> Delayed f a -- | Index a delayed array, returning a IndexOutOfBounds exception -- if the index is out of range. indexDelayed :: Shape f => Delayed f a -> f Int -> a -- | manifest an array to a SArray and delay again. affirm :: (Shape f, Storable a) => Delayed f a -> Delayed f a -- | seqManifest an array to a SArray and delay again. seqAffirm :: (Shape f, Storable a) => Delayed f a -> Delayed f a -- | A delayed representation of an array with a focus on a single element. -- This element is the target of extract. data Focused f a -- | Focus on a particular element of a delayed array. focusOn :: f Int -> Delayed f a -> Focused f a -- | Discard the focus to retrieve the delayed array. unfocus :: Focused f a -> Delayed f a -- | Indexed lens onto the delayed array, indexed at the focus. unfocused :: IndexedLens (f Int) (Focused f a) (Focused f b) (Delayed f a) (Delayed f b) -- | Modify a Delayed array by extracting a value from a -- Focused each point. extendFocus :: Shape f => (Focused f a -> b) -> Delayed f a -> Delayed f b -- | Lens onto the position of a ComonadStore. -- --
--   locale :: Lens' (Focused l a) (l Int)
--   
locale :: ComonadStore s w => Lens' (w a) s -- | Focus on a neighbouring element, relative to the current focus. shiftFocus :: Applicative f => f Int -> Focused f a -> Focused f a -- | Pass a pointer to the array's data to the IO action. Modifying data -- through the Ptr is unsafe. unsafeWithPtr :: Storable a => SArray f a -> (Ptr a -> IO b) -> IO b -- | Yield the underlying ForeignPtr. Modifying the data through the -- ForeignPtr is unsafe. unsafeToForeignPtr :: Storable a => SArray f a -> ForeignPtr a -- | O(1) Create an array from a layout and ForeignPtr. It is -- assumed the pointer points directly to the data (no offset). Modifying -- data through the ForeignPtr afterwards is unsafe. unsafeFromForeignPtr :: (Shape f, Storable a) => Layout f -> ForeignPtr a -> SArray f a -- | Contains QuasiQuotes and TemplateHaskell utilities for creating dense -- arrays, stencils and fixed length vectors. -- -- The parser for the QuasiQuotes is still a work in progress. module Data.Dense.TH -- | QuasiQuoter for producing a dense arrays using a custom parser. Values -- are space separated, while also allowing infix expressions (like -- 5/7). If you want to apply a function, it should be done in -- brackets. Supports 1D, 2D and 3D arrays. -- -- The number of rows/columns must be consistent thought out the array. -- --

Examples

-- -- -- --
--   [dense| 5 -3 1 -3 5 |] :: (R1 f, Vector v a, Num a) => Array v f a
--   
-- -- -- --
--   chars :: UArray V2 Char
--   chars :: [dense|
--     'a' 'b' 'c'
--     'd' 'e' 'f'
--     'g' 'h' 'i'
--   |]
--   
-- -- -- --
--   a :: BArray V3 String
--   a = [dense|
--     "000" "100" "200"
--     "010" "110" "210"
--     "020" "120" "220"
--   
--     "001" "101" "201"
--     "011" "111" "211"
--     "021" "121" "221"
--   
--     "002" "102" "202"
--     "012" "112" "212"
--     "022" "122" "222"
--   |]
--   
dense :: QuasiQuoter -- | Type safe QuasiQuoter for fixed length vectors V. Values -- are space separated. Can be used as expressions or patterns. -- --
--   [v| x y z w q r |] :: V 6 a
--   
-- -- Note this requires DataKinds. Also requires -- ViewPatterns if v is used as a pattern. -- --

Examples

-- --
--   >>> let a = [v| 1 2 3 4 5 |]
--   >>> :t a
--   a :: Num a => V 5 a
--   >>> a
--   V {toVector = [1,2,3,4,5]}
--   >>> let f [v| a b c d e |] = (a,b,c,d,e)
--   >>> :t f
--   f :: V 5 t -> (t, t, t, t, t)
--   >>> f a
--   (1,2,3,4,5)
--   
-- -- Variables and infix expressions are also allowed. Negative values can -- be expressed by a leading - with a space before but no space -- after. -- --
--   >>> let b x = [v| 1/x 2 / x (succ x)**2 x-2 x - 3 -x |]
--   >>> b Debug.SimpleReflect.a
--   V {toVector = [1 / a,2 / a,succ a**2,a - 2,a - 3,negate a]}
--   
v :: QuasiQuoter -- | QuasiQuoter for producing a static stencil definition. This is a -- versatile parser for 1D, 2D and 3D stencils. The parsing is similar to -- dense but stencil also supports _, which means -- ignore this element. Also, stencils should have an odd length in all -- dimensions so there is always a center element (which is used as -- zero). -- --

Examples

-- -- -- --
--   [stencil| 5 -3 1 -3 5 |] :: Num a => Stencil V1 a
--   
-- -- -- --
--   myStencil2 :: Num a => Stencil V2 a
--   myStencil2 = [stencil|
--     0 1 0
--     1 0 1
--     0 1 0
--   |]
--   
-- -- -- --
--   myStencil3 :: Fractional a => Stencil V3 a
--   myStencil3 :: [stencil|
--     1/20 3/10 1/20
--     3/10  1   3/10
--     1/20 3/10 1/20
--   
--     3/10  1   3/10
--      1    _    1
--     3/10  1   3/10
--   
--     1/20 3/10 1/20
--     3/10  1   3/10
--     1/20 3/10 1/20
--   |]
--   
-- -- Variables can also be used -- --
--   myStencil2' :: a -> a -> a -> Stencil V2 a
--   myStencil2' a b c = [stencil|
--     c b c
--     b a b
--     c b c
--   |]
--   
stencil :: QuasiQuoter -- | Class of shapes that can be lifted. -- -- This is to prevent orphans for the Lift class. class Shape f => ShapeLift f -- | lift for Shapes. liftShape :: (ShapeLift f, Lift a) => f a -> Q Exp -- | Polymorphic lift for a Shapes. liftShape' :: (ShapeLift f, Lift a) => f a -> Q Exp -- | Construct a Stencil by unrolling the list at compile time. For -- example -- --
--   ifoldr f b $(mkStencilTH [(V1 (-1), 5), (V1 0, 3), (V1 1, 5)])
--   
-- -- will be get turned into -- --
--   f (V1 (-1)) 5 (f (V1 0) 3 (f (V1 1) 5 b))
--   
-- -- at compile time. Since there are no loops and all target indexes are -- known at compile time, this can lead to more optimisations and faster -- execution times. This can lead to around a 2x speed up compared to -- folding over unboxed vectors. -- --
--   myStencil = $(mkStencilTH (as :: [(f Int, a)])) :: Stencil f a
--   
mkStencilTH :: (ShapeLift f, Lift a) => [(f Int, a)] -> Q Exp -- | mkStencilTH with a custom lift function for a. mkStencilTHBy :: ShapeLift f => (a -> Q Exp) -> [(f Int, a)] -> Q Exp instance Data.Dense.TH.ShapeLift Linear.V1.V1 instance Data.Dense.TH.ShapeLift Linear.V2.V2 instance Data.Dense.TH.ShapeLift Linear.V3.V3 instance Data.Dense.TH.ShapeLift Linear.V4.V4 -- | This module provides a large subset of the full functionality of -- "dense" without exporting names that conflict with names in prelude, -- so it can often be imported unqualified. It also includes reexported -- classes and data types from other modules. However it does not contain -- much functions necessary to construct arrays, for that see -- Data.Dense.Generic or one of the type specific modules intended -- to be imported qualified. Typical imports for shaped will look like -- this: -- --
--   import           Data.Dense
--   import qualified Data.Dense.Unboxed as U
--   
-- -- For boxed-specific arrays (a la Data.Vector) see -- Data.Dense.Boxed. module Data.Dense -- | An Array is a vector with a shape. data Array v f a -- | Boxed array. type BArray = Array Vector -- | Unboxed array. type UArray = Array Vector -- | Storeable array. type SArray = Array Vector -- | Prim array. type PArray = Array Vector -- | A Layout is the full size of an array. This alias is used to -- help distinguish between the layout of an array and an index (usually -- just l Int) in a type signature. type Layout f = f Int -- | Class of things that have a Layout. This means we can use the -- same functions for the various different arrays in the library. class Shape f => HasLayout f a | a -> f -- | Lens onto the Layout of something. layout :: HasLayout f a => Lens' a (Layout f) -- | Lens onto the Layout of something. layout :: (HasLayout f a, a ~ f Int) => (Layout f -> g (Layout f)) -> a -> g a -- | Class for types that can be converted to and from linear indexes. class (Eq1 f, Additive f, Traversable f) => Shape f -- | Get the extent of an array. -- --
--   extent :: Array v f a    -> f Int
--   extent :: MArray v f s a -> f Int
--   extent :: Delayed f a    -> f Int
--   extent :: Focused f a    -> f Int
--   
extent :: HasLayout f a => a -> f Int -- | Get the total number of elements in an array. -- --
--   size :: Array v f a    -> Int
--   size :: MArray v f s a -> Int
--   size :: Delayed f a    -> Int
--   size :: Focused f a    -> Int
--   
size :: HasLayout f a => a -> Int -- | Indexed fold for all the indexes in the layout. indexes :: HasLayout f a => IndexedFold Int a (f Int) -- | Indexed fold between the two indexes where the index is the linear -- index for the original layout. indexesBetween :: HasLayout f a => f Int -> f Int -> IndexedFold Int a (f Int) -- | Indexed fold starting starting from some point, where the index is the -- linear index for the original layout. indexesFrom :: HasLayout f a => f Int -> IndexedFold Int a (f Int) -- | Indexed lens over the underlying vector of an array. The index is the -- extent of the array. You must _not_ change the length of the -- vector, otherwise an error will be thrown (even for V1 layouts, -- use flat for V1). vector :: (Vector v a, Vector w b) => IndexedLens (Layout f) (Array v f a) (Array w f b) (v a) (w b) -- | Indexed traversal over the elements of an array. The index is the -- current position in the array. values :: (Shape f, Vector v a, Vector w b) => IndexedTraversal (f Int) (Array v f a) (Array w f b) a b -- | Same as values but restrictive in the vector type. values' :: (Shape f, Vector v a, Vector v b) => IndexedTraversal (f Int) (Array v f a) (Array v f b) a b -- | Traverse over the values between two indexes. valuesBetween :: (Shape f, Vector v a) => f Int -> f Int -> IndexedTraversal' (f Int) (Array v f a) a -- | 1D arrays are just vectors. You are free to change the length of the -- vector when going over this Iso (unlike -- linear). -- -- Note that V1 arrays are an instance of Vector so you can -- use any of the functions in Data.Vector.Generic on them without -- needing to convert. flat :: Vector w b => Iso (Array v V1 a) (Array w V1 b) (v a) (w b) -- | O(n) Convert the first n elements of a list to an Array with -- the given shape. Returns Nothing if there are not enough -- elements in the list. fromListInto :: (Shape f, Vector v a) => Layout f -> [a] -> Maybe (Array v f a) -- | O(n) Convert the first n elements of a list to an Array with -- the given shape. Throw an error if the list is not long enough. fromListInto_ :: (Shape f, Vector v a) => Layout f -> [a] -> Array v f a -- | Create an array from a vector and a layout. Return -- Nothing if the vector is not the right shape. fromVectorInto :: (Shape f, Vector v a) => Layout f -> v a -> Maybe (Array v f a) -- | Create an array from a vector and a layout. Throws an -- error if the vector is not the right shape. fromVectorInto_ :: (Shape f, Vector v a) => Layout f -> v a -> Array v f a -- | Affine traversal over a single row in a matrix. -- --
--   >>> traverseOf_ rows print $ m & ixRow 1 . each *~ 2
--   [a,b,c,d]
--   [e * 2,f * 2,g * 2,h * 2]
--   [i,j,k,l]
--   
-- -- The row vector should remain the same size to satisfy traversal laws -- but give reasonable behaviour if the size differs: -- --
--   >>> traverseOf_ rows print $ m & ixRow 1 .~ B.fromList [0,1]
--   [a,b,c,d]
--   [0,1,g,h]
--   [i,j,k,l]
--   
-- --
--   >>> traverseOf_ rows print $ m & ixRow 1 .~ B.fromList [0..100]
--   [a,b,c,d]
--   [0,1,2,3]
--   [i,j,k,l]
--   
ixRow :: Vector v a => Int -> IndexedTraversal' Int (Array v V2 a) (v a) -- | Indexed traversal over the rows of a matrix. Each row is an efficient -- slice of the original vector. -- --
--   >>> traverseOf_ rows print m
--   [a,b,c,d]
--   [e,f,g,h]
--   [i,j,k,l]
--   
rows :: (Vector v a, Vector w b) => IndexedTraversal Int (Array v V2 a) (Array w V2 b) (v a) (w b) -- | Affine traversal over a single column in a matrix. -- --
--   >>> traverseOf_ rows print $ m & ixColumn 2 . each +~ 1
--   [a,b,c + 1,d]
--   [e,f,g + 1,h]
--   [i,j,k + 1,l]
--   
ixColumn :: Vector v a => Int -> IndexedTraversal' Int (Array v V2 a) (v a) -- | Indexed traversal over the columns of a matrix. Unlike rows, -- each column is a new separate vector. -- --
--   >>> traverseOf_ columns print m
--   [a,e,i]
--   [b,f,j]
--   [c,g,k]
--   [d,h,l]
--   
-- --
--   >>> traverseOf_ rows print $ m & columns . indices odd . each .~ 0
--   [a,0,c,0]
--   [e,0,g,0]
--   [i,0,k,0]
--   
-- -- The vectors should be the same size to be a valid traversal. If the -- vectors are different sizes, the number of rows in the new array will -- be the length of the smallest vector. columns :: (Vector v a, Vector w b) => IndexedTraversal Int (Array v V2 a) (Array w V2 b) (v a) (w b) -- | Traversal over a single plane of a 3D array given a lens onto that -- plane (like _xy, _yz, _zx). ixPlane :: Vector v a => ALens' (V3 Int) (V2 Int) -> Int -> IndexedTraversal' Int (Array v V3 a) (Array v V2 a) -- | Traversal over all planes of 3D array given a lens onto that plane -- (like _xy, _yz, _zx). planes :: (Vector v a, Vector w b) => ALens' (V3 Int) (V2 Int) -> IndexedTraversal Int (Array v V3 a) (Array w V3 b) (Array v V2 a) (Array w V2 b) -- | Flatten a plane by reducing a vector in the third dimension to a -- single value. flattenPlane :: (Vector v a, Vector w b) => ALens' (V3 Int) (V2 Int) -> (v a -> b) -> Array v V3 a -> Array w V2 b -- | A mutable array with a shape. data MArray v l s a -- | Boxed mutable array. type BMArray = MArray MVector -- | Unboxed mutable array. type UMArray = MArray MVector -- | Storable mutable array. type SMArray = MArray MVector -- | Primitive mutable array. type PMArray = MArray MVector -- | A delayed representation of an array. This useful for mapping over an -- array in parallel. data Delayed f a -- | Isomorphism between an array and its delayed representation. -- Conversion to the array is done in parallel. delayed :: (Vector v a, Vector w b, Shape f, Shape g) => Iso (Array v f a) (Array w g b) (Delayed f a) (Delayed g b) -- | Isomorphism between an array and its delayed representation. -- Conversion to the array is done in parallel. seqDelayed :: (Vector v a, Vector w b, Shape f, Shape g) => Iso (Array v f a) (Array w g b) (Delayed f a) (Delayed g b) -- | Turn a material array into a delayed one with the same shape. delay :: (Vector v a, Shape f) => Array v f a -> Delayed f a -- | Parallel manifestation of a delayed array into a material one. manifest :: (Vector v a, Shape f) => Delayed f a -> Array v f a -- | Sequential manifestation of a delayed array. seqManifest :: (Vector v a, Shape f) => Delayed f a -> Array v f a -- | Generate a Delayed array using the given Layout and -- construction function. genDelayed :: Layout f -> (f Int -> a) -> Delayed f a -- | Index a delayed array, returning a IndexOutOfBounds exception -- if the index is out of range. indexDelayed :: Shape f => Delayed f a -> f Int -> a -- | manifest an array to a UArray and delay again. See -- Data.Dense.Boxed or Data.Dense.Storable to affirm -- for other types of arrays. affirm :: (Shape f, Unbox a) => Delayed f a -> Delayed f a -- | seqManifest an array to a UArray and delay again. See -- Data.Dense.Boxed or Data.Dense.Storable to affirm -- for other types of arrays. seqAffirm :: (Shape f, Unbox a) => Delayed f a -> Delayed f a -- | Compute the left scalar product -- --
--   >>> 2 *^ V2 3 4
--   V2 6 8
--   
(*^) :: (Functor f, Num a) => a -> f a -> f a infixl 7 *^ -- | Compute the right scalar product -- --
--   >>> V2 3 4 ^* 2
--   V2 6 8
--   
(^*) :: (Functor f, Num a) => f a -> a -> f a infixl 7 ^* -- | Compute division by a scalar on the right. (^/) :: (Functor f, Fractional a) => f a -> a -> f a infixl 7 ^/ -- | A vector is an additive group with additional structure. class Functor f => Additive (f :: Type -> Type) -- | The zero vector zero :: (Additive f, Num a) => f a -- | Compute the sum of two vectors -- --
--   >>> V2 1 2 ^+^ V2 3 4
--   V2 4 6
--   
(^+^) :: (Additive f, Num a) => f a -> f a -> f a -- | Compute the difference between two vectors -- --
--   >>> V2 4 5 ^-^ V2 3 1
--   V2 1 4
--   
(^-^) :: (Additive f, Num a) => f a -> f a -> f a -- | Linearly interpolate between two vectors. lerp :: (Additive f, Num a) => a -> f a -> f a -> f a -- | Apply a function to merge the 'non-zero' components of two vectors, -- unioning the rest of the values. -- -- liftU2 :: Additive f => (a -> a -> a) -> f a -> f a -> f a -- | Apply a function to the components of two vectors. -- -- liftI2 :: Additive f => (a -> b -> c) -> f a -> f b -> f c infixl 6 ^+^ infixl 6 ^-^ -- | Free and sparse inner product/metric spaces. class Additive f => Metric (f :: Type -> Type) -- | Compute the inner product of two vectors or (equivalently) convert a -- vector f a into a covector f a -> a. -- --
--   >>> V2 1 2 `dot` V2 3 4
--   11
--   
dot :: (Metric f, Num a) => f a -> f a -> a -- | Compute the squared norm. The name quadrance arises from Norman J. -- Wildberger's rational trigonometry. quadrance :: (Metric f, Num a) => f a -> a -- | Compute the quadrance of the difference qd :: (Metric f, Num a) => f a -> f a -> a -- | Compute the distance between two vectors in a metric space distance :: (Metric f, Floating a) => f a -> f a -> a -- | Compute the norm of a vector in a metric space norm :: (Metric f, Floating a) => f a -> a -- | Convert a non-zero vector to unit vector. signorm :: (Metric f, Floating a) => f a -> f a -- | A delayed representation of an array with a focus on a single element. -- This element is the target of extract. data Focused f a -- | Focus on a particular element of a delayed array. focusOn :: f Int -> Delayed f a -> Focused f a -- | Discard the focus to retrieve the delayed array. unfocus :: Focused f a -> Delayed f a -- | Indexed lens onto the delayed array, indexed at the focus. unfocused :: IndexedLens (f Int) (Focused f a) (Focused f b) (Delayed f a) (Delayed f b) -- | Modify a Delayed array by extracting a value from a -- Focused each point. extendFocus :: Shape f => (Focused f a -> b) -> Delayed f a -> Delayed f b -- | Lens onto the position of a ComonadStore. -- --
--   locale :: Lens' (Focused l a) (l Int)
--   
locale :: ComonadStore s w => Lens' (w a) s -- | Focus on a neighbouring element, relative to the current focus. shiftFocus :: Applicative f => f Int -> Focused f a -> Focused f a -- | The boundary condition used for indexing relative elements in a -- Focused. data Boundary -- | clamp coordinates to the extent of the array Clamp :: Boundary -- | mirror coordinates beyond the array extent Mirror :: Boundary -- | wrap coordinates around on each dimension Wrap :: Boundary -- | Index a focused using a Boundary condition. peekB :: Shape f => Boundary -> f Int -> Focused f a -> a -- | Index an element by applying a function the current position, using a -- boundary condition. peeksB :: Shape f => Boundary -> (f Int -> f Int) -> Focused f a -> a -- | Index an element relative to the current focus using a Boundary -- condition. peekRelativeB :: Shape f => Boundary -> f Int -> Focused f a -> a -- | There are two ways to define a comonad: -- -- I. Provide definitions for extract and extend satisfying -- these laws: -- --
--   extend extract      = id
--   extract . extend f  = f
--   extend f . extend g = extend (f . extend g)
--   
-- -- In this case, you may simply set fmap = liftW. -- -- These laws are directly analogous to the laws for monads and perhaps -- can be made clearer by viewing them as laws stating that Cokleisli -- composition must be associative, and has extract for a unit: -- --
--   f =>= extract   = f
--   extract =>= f   = f
--   (f =>= g) =>= h = f =>= (g =>= h)
--   
-- -- II. Alternately, you may choose to provide definitions for -- fmap, extract, and duplicate satisfying these -- laws: -- --
--   extract . duplicate      = id
--   fmap extract . duplicate = id
--   duplicate . duplicate    = fmap duplicate . duplicate
--   
-- -- In this case you may not rely on the ability to define fmap in -- terms of liftW. -- -- You may of course, choose to define both duplicate and -- extend. In that case you must also satisfy these laws: -- --
--   extend f  = fmap f . duplicate
--   duplicate = extend id
--   fmap f    = extend (f . extract)
--   
-- -- These are the default definitions of extend and -- duplicate and the definition of liftW respectively. class Functor w => Comonad (w :: Type -> Type) -- |
--   extract . fmap f = f . extract
--   
extract :: Comonad w => w a -> a -- |
--   duplicate = extend id
--   fmap (fmap f) . duplicate = duplicate . fmap f
--   
duplicate :: Comonad w => w a -> w (w a) -- |
--   extend f = fmap f . duplicate
--   
extend :: Comonad w => (w a -> b) -> w a -> w b class Comonad w => ComonadStore s (w :: Type -> Type) | w -> s pos :: ComonadStore s w => w a -> s peek :: ComonadStore s w => s -> w a -> a peeks :: ComonadStore s w => (s -> s) -> w a -> a seek :: ComonadStore s w => s -> w a -> w a seeks :: ComonadStore s w => (s -> s) -> w a -> w a experiment :: (ComonadStore s w, Functor f) => (s -> f s) -> w a -> f a -- | Stencils are used to fold over neighbouring array sites. To construct -- a stencil use mkStencil, mkStencilUnboxed. For static -- sized stencils you can use the quasiquoter stencil. -- -- To use a stencil you can use stencilSum or use the -- Foldable and FoldableWithIndex instances. data Stencil f a -- | QuasiQuoter for producing a static stencil definition. This is a -- versatile parser for 1D, 2D and 3D stencils. The parsing is similar to -- dense but stencil also supports _, which means -- ignore this element. Also, stencils should have an odd length in all -- dimensions so there is always a center element (which is used as -- zero). -- --

Examples

-- -- -- --
--   [stencil| 5 -3 1 -3 5 |] :: Num a => Stencil V1 a
--   
-- -- -- --
--   myStencil2 :: Num a => Stencil V2 a
--   myStencil2 = [stencil|
--     0 1 0
--     1 0 1
--     0 1 0
--   |]
--   
-- -- -- --
--   myStencil3 :: Fractional a => Stencil V3 a
--   myStencil3 :: [stencil|
--     1/20 3/10 1/20
--     3/10  1   3/10
--     1/20 3/10 1/20
--   
--     3/10  1   3/10
--      1    _    1
--     3/10  1   3/10
--   
--     1/20 3/10 1/20
--     3/10  1   3/10
--     1/20 3/10 1/20
--   |]
--   
-- -- Variables can also be used -- --
--   myStencil2' :: a -> a -> a -> Stencil V2 a
--   myStencil2' a b c = [stencil|
--     c b c
--     b a b
--     c b c
--   |]
--   
stencil :: QuasiQuoter -- | Make a stencil folding over a list. -- -- If the list is staticlly known this should expand at compile time via -- rewrite rules, similar to makeStencilTH but less reliable. If -- that does not happen the resulting could be slow. If the list is not -- know at compile time, mkStencilUnboxed can be signifcantly -- faster (but isn't subject expending via rewrite rules). mkStencil :: [(f Int, a)] -> Stencil f a -- | Construct a Stencil by unrolling the list at compile time. For -- example -- --
--   ifoldr f b $(mkStencilTH [(V1 (-1), 5), (V1 0, 3), (V1 1, 5)])
--   
-- -- will be get turned into -- --
--   f (V1 (-1)) 5 (f (V1 0) 3 (f (V1 1) 5 b))
--   
-- -- at compile time. Since there are no loops and all target indexes are -- known at compile time, this can lead to more optimisations and faster -- execution times. This can lead to around a 2x speed up compared to -- folding over unboxed vectors. -- --
--   myStencil = $(mkStencilTH (as :: [(f Int, a)])) :: Stencil f a
--   
mkStencilTH :: (ShapeLift f, Lift a) => [(f Int, a)] -> Q Exp -- | Sum the elements around a Focused using a Boundary -- condition and a Stencil. -- -- This is often used in conjunction with extendFocus. stencilSum :: (Shape f, Num a) => Boundary -> Stencil f a -> Focused f a -> a -- | A 1-dimensional vector -- --
--   >>> pure 1 :: V1 Int
--   V1 1
--   
-- --
--   >>> V1 2 + V1 3
--   V1 5
--   
-- --
--   >>> V1 2 * V1 3
--   V1 6
--   
-- --
--   >>> sum (V1 2)
--   2
--   
newtype V1 a V1 :: a -> V1 a -- | A 2-dimensional vector -- --
--   >>> pure 1 :: V2 Int
--   V2 1 1
--   
-- --
--   >>> V2 1 2 + V2 3 4
--   V2 4 6
--   
-- --
--   >>> V2 1 2 * V2 3 4
--   V2 3 8
--   
-- --
--   >>> sum (V2 1 2)
--   3
--   
data V2 a V2 :: !a -> !a -> V2 a -- | A 3-dimensional vector data V3 a V3 :: !a -> !a -> !a -> V3 a -- | A 4-dimensional vector. data V4 a V4 :: !a -> !a -> !a -> !a -> V4 a -- | A space that has at least 1 basis vector _x. class R1 (t :: Type -> Type) -- |
--   >>> V1 2 ^._x
--   2
--   
-- --
--   >>> V1 2 & _x .~ 3
--   V1 3
--   
_x :: R1 t => Lens' (t a) a -- | A space that distinguishes 2 orthogonal basis vectors _x and -- _y, but may have more. class R1 t => R2 (t :: Type -> Type) -- |
--   >>> V2 1 2 ^._y
--   2
--   
-- --
--   >>> V2 1 2 & _y .~ 3
--   V2 1 3
--   
_y :: R2 t => Lens' (t a) a _xy :: R2 t => Lens' (t a) (V2 a) -- | A space that distinguishes 3 orthogonal basis vectors: _x, -- _y, and _z. (It may have more) class R2 t => R3 (t :: Type -> Type) -- |
--   >>> V3 1 2 3 ^. _z
--   3
--   
_z :: R3 t => Lens' (t a) a _xyz :: R3 t => Lens' (t a) (V3 a) -- | A space that distinguishes orthogonal basis vectors _x, -- _y, _z, _w. (It may have more.) class R3 t => R4 (t :: Type -> Type) -- |
--   >>> V4 1 2 3 4 ^._w
--   4
--   
_w :: R4 t => Lens' (t a) a _xyzw :: R4 t => Lens' (t a) (V4 a) _xz :: forall (t :: Type -> Type) a. R3 t => Lens' (t a) (V2 a) _yz :: forall (t :: Type -> Type) a. R3 t => Lens' (t a) (V2 a) -- |
--   >>> V2 1 2 ^. _yx
--   V2 2 1
--   
_yx :: forall (t :: Type -> Type) a. R2 t => Lens' (t a) (V2 a) _zy :: forall (t :: Type -> Type) a. R3 t => Lens' (t a) (V2 a) _zx :: forall (t :: Type -> Type) a. R3 t => Lens' (t a) (V2 a) -- | Unboxed multidimensional arrays. module Data.Dense.Unboxed -- | Unboxed array. type UArray = Array Vector class (Vector Vector a, MVector MVector a) => Unbox a -- | Class for types that can be converted to and from linear indexes. class (Eq1 f, Additive f, Traversable f) => Shape f -- | Class of things that have a Layout. This means we can use the -- same functions for the various different arrays in the library. class Shape f => HasLayout f a | a -> f -- | Lens onto the Layout of something. layout :: HasLayout f a => Lens' a (Layout f) -- | Lens onto the Layout of something. layout :: (HasLayout f a, a ~ f Int) => (Layout f -> g (Layout f)) -> a -> g a -- | A Layout is the full size of an array. This alias is used to -- help distinguish between the layout of an array and an index (usually -- just l Int) in a type signature. type Layout f = f Int -- | Get the extent of an array. -- --
--   extent :: Array v f a    -> f Int
--   extent :: MArray v f s a -> f Int
--   extent :: Delayed f a    -> f Int
--   extent :: Focused f a    -> f Int
--   
extent :: HasLayout f a => a -> f Int -- | Get the total number of elements in an array. -- --
--   size :: Array v f a    -> Int
--   size :: MArray v f s a -> Int
--   size :: Delayed f a    -> Int
--   size :: Focused f a    -> Int
--   
size :: HasLayout f a => a -> Int -- | Indexed fold for all the indexes in the layout. indexes :: HasLayout f a => IndexedFold Int a (f Int) -- | Indexed fold starting starting from some point, where the index is the -- linear index for the original layout. indexesFrom :: HasLayout f a => f Int -> IndexedFold Int a (f Int) -- | Indexed fold between the two indexes where the index is the linear -- index for the original layout. indexesBetween :: HasLayout f a => f Int -> f Int -> IndexedFold Int a (f Int) -- | Indexed lens over the underlying vector of an array. The index is the -- extent of the array. You must _not_ change the length of the -- vector, otherwise an error will be thrown (even for V1 layouts, -- use flat for V1). vector :: (Unbox a, Unbox b) => IndexedLens (Layout f) (UArray f a) (UArray f b) (Vector a) (Vector b) -- | Same as values but restrictive in the vector type. values :: (Shape f, Unbox a, Unbox b) => IndexedTraversal (f Int) (UArray f a) (UArray f b) a b -- | Same as values but restrictive in the vector type. values' :: (Shape f, Unbox a, Unbox b) => IndexedTraversal (f Int) (UArray f a) (UArray f b) a b -- | Same as values but restrictive in the vector type. valuesBetween :: (Shape f, Unbox a) => f Int -> f Int -> IndexedTraversal' (f Int) (UArray f a) a -- | 1D arrays are just vectors. You are free to change the length of the -- vector when going over this Iso (unlike -- linear). -- -- Note that V1 arrays are an instance of Vector so you can -- use any of the functions in Generic on them without needing to -- convert. flat :: Unbox b => Iso (UArray V1 a) (UArray V1 b) (Vector a) (Vector b) -- | Contruct a flat array from a list. (This is just fromList from -- Generic.) fromList :: Unbox a => [a] -> UArray V1 a -- | O(n) Convert the first n elements of a list to an UArrayith -- the given shape. Returns Nothing if there are not enough -- elements in the list. fromListInto :: (Shape f, Unbox a) => Layout f -> [a] -> Maybe (UArray f a) -- | O(n) Convert the first n elements of a list to an UArrayith -- the given shape. Throw an error if the list is not long enough. fromListInto_ :: (Shape f, Unbox a) => Layout f -> [a] -> UArray f a -- | Create an array from a vector and a layout. Return -- Nothing if the vector is not the right shape. fromVectorInto :: (Shape f, Unbox a) => Layout f -> Vector a -> Maybe (UArray f a) -- | Create an array from a vector and a layout. Throws an -- error if the vector is not the right shape. fromVectorInto_ :: (Shape f, Unbox a) => Layout f -> Vector a -> UArray f a -- | O(n) UArray of the given shape with the same value in each position. replicate :: (Shape f, Unbox a) => f Int -> a -> UArray f a -- | O(n) Construct an array of the given shape by applying the function to -- each index. generate :: (Shape f, Unbox a) => Layout f -> (f Int -> a) -> UArray f a -- | O(n) Construct an array of the given shape by applying the function to -- each index. linearGenerate :: (Shape f, Unbox a) => Layout f -> (Int -> a) -> UArray f a -- | Execute the monadic action and freeze the resulting array. create :: Unbox a => (forall s. ST s (UMArray f s a)) -> UArray f a -- | O(n) Construct an array of the given shape by filling each position -- with the monadic value. replicateM :: (Monad m, Shape f, Unbox a) => Layout f -> m a -> m (UArray f a) -- | O(n) Construct an array of the given shape by applying the monadic -- function to each index. generateM :: (Monad m, Shape f, Unbox a) => Layout f -> (f Int -> m a) -> m (UArray f a) -- | O(n) Construct an array of the given shape by applying the monadic -- function to each index. linearGenerateM :: (Monad m, Shape f, Unbox a) => Layout f -> (Int -> m a) -> m (UArray f a) -- | The empty UArray with a zero shape. empty :: (Unbox a, Additive f) => UArray f a -- | Test is if the array is empty. null :: Foldable f => UArray f a -> Bool -- | Index an element of an array. Throws IndexOutOfBounds if the -- index is out of bounds. (!) :: (Shape f, Unbox a) => UArray f a -> f Int -> a -- | Safe index of an element. (!?) :: (Shape f, Unbox a) => UArray f a -> f Int -> Maybe a -- | Index an element of an array without bounds checking. unsafeIndex :: (Shape f, Unbox a) => UArray f a -> f Int -> a -- | Index an element of an array while ignoring its shape. linearIndex :: Unbox a => UArray f a -> Int -> a -- | Index an element of an array while ignoring its shape, without bounds -- checking. unsafeLinearIndex :: Unbox a => UArray f a -> Int -> a -- | O(1) Indexing in a monad. -- -- The monad allows operations to be strict in the vector when necessary. -- Suppose vector copying is implemented like this: -- --
--   copy mv v = ... write mv i (v ! i) ...
--   
-- -- For lazy vectors, v ! i would not be evaluated which means -- that mv would unnecessarily retain a reference to v -- in each element written. -- -- With indexM, copying can be implemented like this instead: -- --
--   copy mv v = ... do
--     x <- indexM v i
--     write mv i x
--   
-- -- Here, no references to v are retained because indexing (but -- not the elements) is evaluated eagerly. -- -- Throws an error if the index is out of range. indexM :: (Shape f, Unbox a, Monad m) => UArray f a -> f Int -> m a -- | O(1) Indexing in a monad without bounds checks. See -- indexM for an explanation of why this is useful. unsafeIndexM :: (Shape f, Unbox a, Monad m) => UArray f a -> f Int -> m a -- | O(1) Indexing in a monad. Throws an error if the index is out -- of range. linearIndexM :: (Shape f, Unbox a, Monad m) => UArray f a -> Int -> m a -- | O(1) Indexing in a monad without bounds checks. See -- indexM for an explanation of why this is useful. unsafeLinearIndexM :: (Unbox a, Monad m) => UArray f a -> Int -> m a -- | For each pair (i,a) from the list, replace the array element at -- position i by a. (//) :: (Unbox a, Shape f) => UArray f a -> [(f Int, a)] -> UArray f a -- | O(m+n) For each pair (i,b) from the list, replace the -- array element a at position i by f a b. accum :: (Shape f, Unbox a) => (a -> b -> a) -> UArray f a -> [(f Int, b)] -> UArray f a -- | O(n) Map a function over an array map :: (Unbox a, Unbox b) => (a -> b) -> UArray f a -> UArray f b -- | O(n) Apply a function to every element of a vector and its -- index imap :: (Shape f, Unbox a, Unbox b) => (f Int -> a -> b) -> UArray f a -> UArray f b -- | Zip two arrays element wise. If the array's don't have the same shape, -- the new array with be the intersection of the two shapes. zip :: (Shape f, Unbox a, Unbox b) => UArray f a -> UArray f b -> UArray f (a, b) -- | Zip three arrays element wise. If the array's don't have the same -- shape, the new array with be the intersection of the two shapes. zip3 :: (Shape f, Unbox a, Unbox b, Unbox c) => UArray f a -> UArray f b -> UArray f c -> UArray f (a, b, c) -- | Zip two arrays using the given function. If the array's don't have the -- same shape, the new array with be the intersection of the two shapes. zipWith :: (Shape f, Unbox a, Unbox b, Unbox c) => (a -> b -> c) -> UArray f a -> UArray f b -> UArray f c -- | Zip three arrays using the given function. If the array's don't have -- the same shape, the new array with be the intersection of the two -- shapes. zipWith3 :: (Shape f, Unbox a, Unbox b, Unbox c, Unbox d) => (a -> b -> c -> d) -> UArray f a -> UArray f b -> UArray f c -> UArray f d -- | Zip two arrays using the given function with access to the index. If -- the array's don't have the same shape, the new array with be the -- intersection of the two shapes. izipWith :: (Shape f, Unbox a, Unbox b, Unbox c) => (f Int -> a -> b -> c) -> UArray f a -> UArray f b -> UArray f c -- | Zip two arrays using the given function with access to the index. If -- the array's don't have the same shape, the new array with be the -- intersection of the two shapes. izipWith3 :: (Shape f, Unbox a, Unbox b, Unbox c, Unbox d) => (f Int -> a -> b -> c -> d) -> UArray f a -> UArray f b -> UArray f c -> UArray f d -- | Affine traversal over a single row in a matrix. -- --
--   >>> traverseOf_ rows print $ m & ixRow 1 . each +~ 2
--   [1,2,3]
--   [6,7,8]
--   
-- -- The row vector should remain the same size to satisfy traversal laws -- but give reasonable behaviour if the size differs: -- --
--   >>> traverseOf_ rows print $ m & ixRow 1 .~ V.fromList [0,1]
--   [1,2,3]
--   [0,1,6]
--   
-- --
--   >>> traverseOf_ rows print $ m & ixRow 1 .~ V.fromList [0..100]
--   [1,2,3]
--   [0,1,2]
--   
ixRow :: Unbox a => Int -> IndexedTraversal' Int (UArray V2 a) (Vector a) -- | Indexed traversal over the rows of a matrix. Each row is an efficient -- slice of the original vector. -- --
--   >>> traverseOf_ rows print m
--   [1,2,3]
--   [4,5,6]
--   
rows :: (Unbox a, Unbox b) => IndexedTraversal Int (UArray V2 a) (UArray V2 b) (Vector a) (Vector b) -- | Affine traversal over a single column in a matrix. -- --
--   >>> traverseOf_ rows print $ m & ixColumn 2 . each *~ 10
--   [1,2,30]
--   [4,5,60]
--   
ixColumn :: Unbox a => Int -> IndexedTraversal' Int (UArray V2 a) (Vector a) -- | Indexed traversal over the columns of a matrix. Unlike rows, -- each column is a new separate vector. -- --
--   >>> traverseOf_ columns print m
--   [1,4]
--   [2,5]
--   [3,6]
--   
-- --
--   >>> traverseOf_ rows print $ m & columns . indices odd . each .~ 0
--   [1,0,3]
--   [4,0,6]
--   
-- -- The vectors should be the same size to be a valid traversal. If the -- vectors are different sizes, the number of rows in the new array will -- be the length of the smallest vector. columns :: (Unbox a, Unbox b) => IndexedTraversal Int (UArray V2 a) (UArray V2 b) (Vector a) (Vector b) -- | Traversal over a single plane of a 3D array given a lens onto that -- plane (like _xy, _yz, _zx). ixPlane :: Unbox a => ALens' (V3 Int) (V2 Int) -> Int -> IndexedTraversal' Int (UArray V3 a) (UArray V2 a) -- | Traversal over all planes of 3D array given a lens onto that plane -- (like _xy, _yz, _zx). planes :: (Unbox a, Unbox b) => ALens' (V3 Int) (V2 Int) -> IndexedTraversal Int (UArray V3 a) (UArray V3 b) (UArray V2 a) (UArray V2 b) -- | Flatten a plane by reducing a vector in the third dimension to a -- single value. flattenPlane :: (Unbox a, Unbox b) => ALens' (V3 Int) (V2 Int) -> (Vector a -> b) -> UArray V3 a -> UArray V2 b -- | This Traversal should not have any duplicates in the list of -- indices. unsafeOrdinals :: (Unbox a, Shape f) => [f Int] -> IndexedTraversal' (f Int) (UArray f a) a -- | Unboxed mutable array. type UMArray = MArray MVector -- | O(n) Yield an immutable copy of the mutable array. thaw :: (PrimMonad m, Unbox a) => UArray f a -> m (UMArray f (PrimState m) a) -- | O(n) Yield a mutable copy of the immutable vector. freeze :: (PrimMonad m, Unbox a) => UMArray f (PrimState m) a -> m (UArray f a) -- | O(1) Unsafely convert an immutable array to a mutable one without -- copying. The immutable array may not be used after this operation. unsafeThaw :: (PrimMonad m, Unbox a) => UArray f a -> m (UMArray f (PrimState m) a) -- | O(1) Unsafe convert a mutable array to an immutable one without -- copying. The mutable array may not be used after this operation. unsafeFreeze :: (PrimMonad m, Unbox a) => UMArray f (PrimState m) a -> m (UArray f a) -- | A delayed representation of an array. This useful for mapping over an -- array in parallel. data Delayed f a -- | Isomorphism between an array and its delayed representation. -- Conversion to the array is done in parallel. delayed :: (Unbox a, Unbox b, Shape f, Shape k) => Iso (UArray f a) (UArray k b) (Delayed f a) (Delayed k b) -- | Isomorphism between an array and its delayed representation. -- Conversion to the array is done in sequence. seqDelayed :: (Unbox a, Unbox b, Shape f, Shape k) => Iso (UArray f a) (UArray k b) (Delayed f a) (Delayed k b) -- | Turn a material array into a delayed one with the same shape. delay :: (Unbox a, Shape f) => UArray f a -> Delayed f a -- | Parallel manifestation of a delayed array into a material one. manifest :: (Unbox a, Shape f) => Delayed f a -> UArray f a -- | Sequential manifestation of a delayed array. seqManifest :: (Unbox a, Shape f) => Delayed f a -> UArray f a -- | Generate a Delayed array using the given Layout and -- construction function. genDelayed :: Layout f -> (f Int -> a) -> Delayed f a -- | Index a delayed array, returning a IndexOutOfBounds exception -- if the index is out of range. indexDelayed :: Shape f => Delayed f a -> f Int -> a -- | manifest an array to a UArray and delay again. affirm :: (Shape f, Unbox a) => Delayed f a -> Delayed f a -- | seqManifest an array to a UArray and delay again. seqAffirm :: (Shape f, Unbox a) => Delayed f a -> Delayed f a -- | A delayed representation of an array with a focus on a single element. -- This element is the target of extract. data Focused f a -- | Focus on a particular element of a delayed array. focusOn :: f Int -> Delayed f a -> Focused f a -- | Discard the focus to retrieve the delayed array. unfocus :: Focused f a -> Delayed f a -- | Indexed lens onto the delayed array, indexed at the focus. unfocused :: IndexedLens (f Int) (Focused f a) (Focused f b) (Delayed f a) (Delayed f b) -- | Modify a Delayed array by extracting a value from a -- Focused each point. extendFocus :: Shape f => (Focused f a -> b) -> Delayed f a -> Delayed f b -- | Lens onto the position of a ComonadStore. -- --
--   locale :: Lens' (Focused l a) (l Int)
--   
locale :: ComonadStore s w => Lens' (w a) s -- | Focus on a neighbouring element, relative to the current focus. shiftFocus :: Applicative f => f Int -> Focused f a -> Focused f a