O(1) - Get the size of a mutable array.
Modulemassiv-1.0.5.0Haskell2010
Data.Massiv.Array.Mutable
- 1 type
- 1 class
- 71 values
- Packagemassiv-1.0.5.0
- Exports78
- LanguageHaskell2010
- LicenceBSD-3-Clause
- SourceCommon.hs
Size
6 declarationsDeprecated. In favor of sizeOfMArray
Get the size of a mutable array.
O(1) - Change the size of a mutable array. Throws SizeElementsMismatchException if total number of elements does not match the supplied array.
O(1) - Change a mutable array to a mutable vector.
O(1) - Slice a mutable array from the outside, while reducing its dimensionality by one. Same as !?> operator, but for mutable arrays.
O(1) - Take all outer slices of a mutable array and construct a delayed vector out of them. In other words it applies outerSliceMArrayM to each outer index. Same as outerSlices function, but for mutable arrays.
Examples
import Data.Massiv.Array as Aarr <- resizeM (Sz2 4 7) $ makeArrayR P Seq (Sz1 28) (+10)arrArray P Seq (Sz (4 :. 7)) [ [ 10, 11, 12, 13, 14, 15, 16 ] , [ 17, 18, 19, 20, 21, 22, 23 ] , [ 24, 25, 26, 27, 28, 29, 30 ] , [ 31, 32, 33, 34, 35, 36, 37 ] ]
Here we can see we can get individual rows from a mutable matrix
marr <- thawS arrimport Control.Monad ((<=<))mapIO_ (print <=< freezeS) $ outerSlicesMArray Seq marrArray P Seq (Sz1 7) [ 10, 11, 12, 13, 14, 15, 16 ]Array P Seq (Sz1 7) [ 17, 18, 19, 20, 21, 22, 23 ]Array P Seq (Sz1 7) [ 24, 25, 26, 27, 28, 29, 30 ]Array P Seq (Sz1 7) [ 31, 32, 33, 34, 35, 36, 37 ]
For the sake of example what if our goal was to mutate array in such a way that rows from the top half were swapped with the bottom half:
(top, bottom) <- splitAtM 1 2 $ outerSlicesMArray Seq marrmapIO_ (print <=< freezeS) topArray P Seq (Sz1 7) [ 10, 11, 12, 13, 14, 15, 16 ]Array P Seq (Sz1 7) [ 17, 18, 19, 20, 21, 22, 23 ]mapIO_ (print <=< freezeS) bottomArray P Seq (Sz1 7) [ 24, 25, 26, 27, 28, 29, 30 ]Array P Seq (Sz1 7) [ 31, 32, 33, 34, 35, 36, 37 ]szipWithM_ (zipSwapM_ 0) top bottomfreezeS marrArray P Seq (Sz (4 :. 7)) [ [ 24, 25, 26, 27, 28, 29, 30 ] , [ 31, 32, 33, 34, 35, 36, 37 ] , [ 10, 11, 12, 13, 14, 15, 16 ] , [ 17, 18, 19, 20, 21, 22, 23 ] ]
Element-wise mutation
14 declarationsO(1) - Lookup an element in the mutable array. Returns Nothing when index is out of bounds.
O(1) - Same as read, but throws IndexOutOfBoundsException on an invalid index.
O(1) - Write an element into the cell of a mutable array. Returns False when index is out of bounds.
O(1) - Same as write, but throws IndexOutOfBoundsException on an invalid index.
modify O(1) - Modify an element in the cell of a mutable array with a supplied action. Returns the previous value, if index was not out of bounds.
modify_ modifyM O(1) - Modify an element in the cell of a mutable array with a supplied action. Throws an IndexOutOfBoundsException exception for invalid index and returns the previous value otherwise.
modifyM_ O(1) - Same as modifyM, but discard the returned element
Examples
:set -XTypeApplicationsimport Control.Monad.STimport Data.Massiv.ArrayrunST $ newMArray' @P @Ix1 @Int (Sz1 3) >>= (\ma -> modifyM_ ma (pure . (+10)) 1 >> freezeS ma)Array P Seq (Sz1 3) [ 0, 10, 0 ]
swapM O(1) - Swap two elements in a mutable array under the supplied indices. Throws an IndexOutOfBoundsException when either one of the indices is out of bounds and elements under those indices otherwise.
O(1) - Same as swapM, but discard the returned elements
Swap elements in the intersection of two mutable arrays starting at the initial index.
Operations on MArray
0 declarationsImmutable conversion
O(n) - Make a mutable copy of a pure array. Keep in mind that both freeze and thaw trigger a copy of the full array.
Example
import Data.Massiv.Array:set -XTypeApplicationsarr <- fromListsM @U @Ix2 @Double Par [[12,21],[13,31]]marr <- thaw arrmodify marr (pure . (+ 10)) (1 :. 0)Just 13.0freeze Par marrArray U Par (Sz (2 :. 2)) [ [ 12.0, 21.0 ] , [ 23.0, 31.0 ] ]
Same as thaw, but restrict computation to sequential only.
Example
import Data.Massiv.Array:set -XOverloadedListsthawS @P @Ix1 @Double [1..10]marr <- thawS @P @Ix1 @Double [1..10]writeM marr 5 100freezeS marrArray P Seq (Sz1 10) [ 1.0, 2.0, 3.0, 4.0, 5.0, 100.0, 7.0, 8.0, 9.0, 10.0 ]
O(n) - Yield an immutable copy of the mutable array. Note that mutable representations have to be the same.
Example
import Data.Massiv.Arraymarr <- newMArray @P (Sz2 2 6) (0 :: Int)forM_ (range Seq 0 (Ix2 1 4)) $ \ix -> write marr ix 9freeze Seq marrArray P Seq (Sz (2 :. 6)) [ [ 9, 9, 9, 9, 0, 0 ] , [ 0, 0, 0, 0, 0, 0 ] ]
Create mutable
Create new mutable array while initializing all elements to the specified value.
O(n) - Initialize a new mutable array. All elements will be set to some default value. For boxed arrays it will be a thunk with Uninitialized exception, while for others it will be simply zeros.
Examples
import Data.Massiv.Arraymarr <- newMArray' (Sz2 2 6) :: IO (MArray RealWorld P Ix2 Int)freeze Seq marrArray P Seq (Sz (2 :. 6)) [ [ 0, 0, 0, 0, 0, 0 ] , [ 0, 0, 0, 0, 0, 0 ] ]
Or using TypeApplications:
:set -XTypeApplicationsnewMArray' @P @Ix2 @Int (Sz2 2 6) >>= freezeSArray P Seq (Sz (2 :. 6)) [ [ 0, 0, 0, 0, 0, 0 ] , [ 0, 0, 0, 0, 0, 0 ] ]newMArray' @B @_ @Int (Sz2 2 6) >>= freezeS*** Exception: Uninitialized
Just like makeMArrayS, but also accepts computation strategy and runs in IO.
Just like makeMArrayLinearS, but also accepts computation strategy and runs in IO.
makeMArrayS Create a mutable array using an index aware generating action.
Same as makeMArrayS, but index supplied to the action is row-major linear index.
Create pure
createArray_ :: (Manifest r e, Index ix, MonadUnliftIO m)=> CompComputation strategy to use after MArray gets frozen and onward.
-> Sz ixSize of the newly created array
-> (Scheduler RealWorld () -> MArray RealWorld r ix e -> m a)An action that should fill all elements of the brand new mutable array
-> m (Array r ix e)
Create a new array by supplying an action that will fill the new blank mutable array. Use createArray if you'd like to keep the result of the filling function.
Examples
:set -XTypeApplicationsimport Data.Massiv.ArraycreateArray_ @P @_ @Int Seq (Sz1 2) (\ s marr -> scheduleWork s (writeM marr 0 10) >> scheduleWork s (writeM marr 1 11))Array P Seq (Sz1 2) [ 10, 11 ]
createArray :: (Manifest r e, Index ix, MonadUnliftIO m)=> CompComputation strategy to use after MArray gets frozen and onward.
-> Sz ixSize of the newly created array
-> (Scheduler RealWorld a -> MArray RealWorld r ix e -> m b)An action that should fill all elements of the brand new mutable array
-> m ([a], Array r ix e)
Just like createArray_, but together with Array it returns results of scheduled filling actions.
createArrayS_ Create a new array by supplying an action that will fill the new blank mutable array. Use createArrayS if you'd like to keep the result of the filling function.
Examples
:set -XTypeApplicationsimport Data.Massiv.ArraycreateArrayS_ @P @_ @Int (Sz1 2) (\ marr -> write marr 0 10 >> write marr 1 12)Array P Seq (Sz1 2) [ 10, 12 ]
createArrayS Just like createArray_, but together with Array it returns the result of the filling action.
Just like createArrayS_, but restricted to ST.
Just like createArrayS, but restricted to ST.
Generate
Just like generateArrayS, except this generator will respect the supplied computation strategy, and for that reason it is restricted to IO.
Just like generateArray, except generating action will receive a row-major linear index.
generateArrayS Sequentially generate a pure array. Much like makeArray creates a pure array this function will use Manifest interface to generate a pure Array in the end, except that computation strategy is set to Seq. Element producing function no longer has to be pure but is a stateful action, becuase it is restricted to PrimMonad thus allows for sharing the state between computation of each element.
Examples
import Data.Massiv.Arrayimport Data.IORefref <- newIORef (0 :: Int)generateArrayS (Sz1 6) (\ i -> modifyIORef' ref (+i) >> print i >> pure i) :: IO (Array U Ix1 Int)012345Array U Seq (Sz1 6) [ 0, 1, 2, 3, 4, 5 ]readIORef ref15
generateArrayLinearS Same as generateArray but with action that accepts row-major linear index.
generateSplitSeedArray :: (Iterator it, Manifest r e, Index ix)=> itIterator
-> gInitial seed
-> (forall s. g -> ST s (g, g))An ST action that can split a seed into two independent seeds. It will be called the same number of times as the number of jobs that will get scheduled during parallelization. Eg. only once for the sequential case.
-> CompComputation strategy.
-> Sz ixResulting size of the array.
-> (forall s. Ix1 -> ix -> g -> ST s (e, g))An ST action that produces a value and the next seed. It takes both versions of the index, in linear and in multi-dimensional forms, as well as the current seeding value. Returns the element for the array cell together with the new seed that will be used for the next element generation
-> (g, [g], Array r ix e)Returned values are:
The final split of the supplied seed.
Results of scheduled jobs in the same order that they where scheduled
Final array that was fully filled using the supplied action and iterator.
Similar to makeSplitSeedArray, except it will produce a Manifest array and will return back the last unused seed together with all final seeds produced by each scheduled job. This function can be thought of as an unfolding done in parallel while iterating in a customizable manner.
Stateful worker threads
Use per worker thread state while generating elements of the array. Very useful for things that are not thread safe.
Same as generateArrayWS, but use linear indexing instead.
Unfold
unfoldrPrimM_ Sequentially unfold an array from the left.
Examples
Create an array with Fibonacci numbers while performing an IO action at each iteration.
import Data.Massiv.ArrayunfoldrPrimM_ (Sz1 10) (\(f0, f1) -> (f0, (f1, f0 + f1)) <$ print f1) (0, 1) :: IO (Array P Ix1 Int)11235813213455Array P Seq (Sz1 10) [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ]
iunfoldrPrimM_ Same as unfoldrPrimM_ but do the unfolding with index aware function.
unfoldrPrimM Just like iunfoldrPrimM, but do the unfolding with index aware function.
iunfoldrPrimM Just like iunfoldrPrimM_, but also returns the final value of the accumulator.
unfoldlPrimM_ Sequentially unfold an array from the left.
Examples
Create an array with Fibonacci numbers starting at the end while performing and IO action on the accumulator for each element of the array.
import Data.Massiv.ArrayunfoldlPrimM_ (Sz1 10) (\a@(f0, f1) -> let fn = f0 + f1 in print a >> return ((f1, fn), f0)) (0, 1) :: IO (Array P Ix1 Int)(0,1)(1,1)(1,2)(2,3)(3,5)(5,8)(8,13)(13,21)(21,34)(34,55)Array P Seq (Sz1 10) [ 34, 21, 13, 8, 5, 3, 2, 1, 1, 0 ]
iunfoldlPrimM_ Same as unfoldlPrimM_ but do the unfolding with index aware function.
unfoldlPrimM Just like iunfoldlPrimM, but do the unfolding with index aware function.
iunfoldlPrimM Just like iunfoldlPrimM_, but also returns the final value of the accumulator.
Mapping
Sequentially loop over a mutable array while modifying each element with an action.
Sequentially loop over a mutable array while reading each element and applying an action to it. There is no mutation to the array, unless the action itself modifies it.
Sequentially loop over a mutable array while modifying each element with an index aware action.
Sequentially loop over a mutable array while reading each element and applying an index aware action to it. There is no mutation to the array, unless the action itself modifies it.
Sequentially loop over a mutable array while modifying each element with an index aware action.
Sequentially loop over a mutable array while reading each element and applying a linear index aware action to it. There is no mutation to the array, unless the action itself modifies it.
Sequentially loop over the intersection of two mutable arrays while reading elements from both and applying an action to it. There is no mutation to the actual arrays, unless the action itself modifies either one of them.
Same as for2PrimM_, but with index aware action.
Modify
Same as withMArray_, but allows to keep artifacts of scheduled tasks.
Create a copy of a pure array, mutate it in place and return its frozen version. The big difference between withMArrayS is that it's not only gonna respect the computation strategy supplied to it while making a copy, but it will also pass extra argumens to the action that suppose to modify the mutable copy of the source array. These two extra arguments are:
Number of capabilities derived from the Computation strategy of the array.
An action that can be used to schedule arbitrary number of jobs that will be executed in parallel.
And, of course, the mutable array itself.
Same as withMArray_, but the array supplied to this function can be any loadable array. For that reason it will be faster if supplied array is delayed.
Same as withMArrayS, but will work with any loadable array.
Same as withMArrayS, except it discards the value produced by the supplied action
Same as withMArrayS_, but will work with any loadable array.
Same as withMArrayS but in ST. This is not only pure, but also the safest way to do mutation to the array.
Same as withMArrayST, but works with any loadable array.
Same as withMArrayS but in ST. This is not only pure, but also the safest way to do mutation to the array.
Same as withMArrayST_, but works with any loadable array.
Initialize
Initialize mutable array to some default value.
Create new mutable array while initializing all elements to some default value.
Computation
6 declarationsManifest arrays are backed by actual memory and values are looked up versus computed as it is with delayed arrays. Because manifest arrays are located in memory their contents can be mutated once thawed into MArray. The process of changed a mutable MArray back into an immutable Array is called freezing.
Instances6Manifest
NFData e => Manifest BN eDefined in massiv-1.0.5.0 · Data.Massiv.Array.Manifest.BoxedStorable e => Manifest S eDefined in massiv-1.0.5.0 · Data.Massiv.Array.Manifest.StorableManifest B eDefined in massiv-1.0.5.0 · Data.Massiv.Array.Manifest.BoxedManifest BL eDefined in massiv-1.0.5.0 · Data.Massiv.Array.Manifest.BoxedPrim e => Manifest P eDefined in massiv-1.0.5.0 · Data.Massiv.Array.Manifest.PrimitiveUnbox e => Manifest U eDefined in massiv-1.0.5.0 · Data.Massiv.Array.Manifest.Unboxed
Instances9NFData, MArray, …
NFData ix => NFData (MArray s P ix e)Defined in massiv-1.0.5.0 · Data.Massiv.Array.Manifest.PrimitiveNFData ix => NFData (MArray s S ix e)Defined in massiv-1.0.5.0 · Data.Massiv.Array.Manifest.StorableNFData ix => NFData (MArray s U ix e)Defined in massiv-1.0.5.0 · Data.Massiv.Array.Manifest.Unboxeddata MArray s BDefined in massiv-1.0.5.0 · Data.Massiv.Array.Manifest.Boxeddata MArray s BLMBLArray !(Sz ix) !Int !(MutableArray s e)
data MArray s BNDefined in massiv-1.0.5.0 · Data.Massiv.Array.Manifest.Boxeddata MArray s PMPArray !(Sz ix) !Int !(MutableByteArray s)
data MArray s SMSArray !(Sz ix) !(ForeignPtr e)
data MArray s UDefined in massiv-1.0.5.0 · Data.Massiv.Array.Manifest.Unboxed
RealWorld is deeply magical. It is primitive, but it is not
unlifted (hence ptrArg). We never manipulate values of type
RealWorld; it's only used in the type system, to parameterise State#.
computeInto Compute an Array while loading the results into the supplied mutable target array. Number of elements for arrays must agree, otherwise SizeElementsMismatchException exception is thrown.
Load a pure array into the newly created mutable array, while respecting computation startegy.
Load sequentially a pure array into the newly created mutable array.