RawArray
seems to be able to efficiently hold integer and floating point data of various sizes.
What is RawArray
good for? How can we use it?
This is a community wiki answer. Feel free to improve it.
RawArray
is an atomic array type that can hold data in any of the following formats:
"Integer8", "UnsignedInteger8", "Integer16", "UnsignedInteger16",
"Integer32", "UnsignedInteger32", "Integer64", "UnsignedInteger64",
"Real32", "Real64", "Complex64", "Complex128"
(Some aliases can also be used for the format names, e.g. "Byte"
= "UnsignedInteger8"
, "Real"
= "Real64"
, etc.)
It can be converted to/from standard numerical arrays.
It can be passed to LibraryLink functions and manipulated in C. The required header file, WolframRawArrayLibrary.h
, was introduced in Mathematica 10.4.
The main use for this data structure appears to be C–Mathematica communication through LibraryLink (??). It allows having expressions which hold our data in its original binary format, and can be manipulated through functions we implement in C/LibraryLink. Indeed, the usual places to come across a RawArray
in Mathematica are inside expressions such as Image
, Audio
, Raster
, ColorProfileData
, etc.
The relevant functions are in the Developer context. Try ?Developer`*Raw*
. Below, you will find example uses for each function:
Create a RawArray out of a normal list:
ra = RawArray["Real64", {1, 2, 3}]
(* RawArray[Real64,<3>] *)
Allocate a 3 by 3 array of 8-bit integers without specifying its data:
ra = Developer`AllocateRawArray["Integer8", {3, 3}]
(* RawArray[Integer8,<3,3>] *)
Developer`RawArrayQ[ra]
(* True *)
Developer`RawArrayType[ra]
(* "Integer8" *)
Convert to 32-bit integers:
ra2 = Developer`RawArrayConvert[ra, "Integer32"]
(* RawArray[Integer32,<3,3>] *)
Convert to a list (actually, packed array):
Developer`FromRawArray[ra]
(* {{-48, 73, -89}, {25, 1, 0}, {0, 0, 0}} *)
Normal[ra]
(* {{-48, 73, -89}, {25, 1, 0}, {0, 0, 0}} *)
Note that when the raw array was allocated, it wasn't initialized. The values inside are unpredictable.
Notes on RawArrayConvert
:
RawArrayConvert
takes a 3rd argument which can be True
or False
and controls how to do the conversion. I do not fully understand this yet, but it appears that:
When converting to a smaller type:
True
takes the upper bitsFalse
takes the lower bitsWhen converting to a larger type:
True
repeats the bits to fill out all the available digitsFalse
only fills in the lower digitsThe default is True
.
RawArray
expressionsThe following functions work and do what you would expect:
Dimensions
, Length
, ArrayDepth
, Flatten
, Join
, Take
, Drop
, TakeDrop
, ArrayReshape
.
SameQ
and Equal
work and require the type to match.
The following do not work:
Part
, Extract
, First
/Rest
/Most
/Last
.
As a general guideline, functions which can potentially return or transform individual elements (such as Part
) do not work.
Note that empty RawArrays decay to {}
, e.g. RawArray["Byte",{}]
-> {}
or Take[ra, 0]
-> {}
.
Missing: What other standard functions can be used on RawArray
?
RawArray
sThe methods in this section work on ByteArray
s as well.
ra[k]
gives the k+1
th element, regardless of rank (i.e. it uses 0-based linear indexing). Warning: Modifying arrays this way is unsafe, as it does not trigger copy-on-write! ra2 = ra; ra2[0] = 0
will modify ra
as well.
ra["Type"]
returns the element type.
ra["Length"]
returns the number of elements. This is not the same as Length[ra]
, which returns the first dimension.
ra["Dimensions"]
returns the dimensions.
ra["Rank"]
returns the tensor rank.
RawArray
objects can be passed between C and Mathematica using LibraryLink. The type specification to use in LibraryFunctionLoad
is "RawArray"
, but RawArray
or LibraryDataType[RawArray]
also work. The type and dimensions cannot be given in the type specification (as they can for packed arrays).
In C,
#include "WolframLibrary.h"
#include "WolframRawArrayLibrary.h"
These headers must be included in this specific order.
The raw array handling functions are in libData->rawarrayLibraryFunctions
instead of libData
. Their names and uses are completely analogous to that of MTensor
handling functions. Look into the header file WolframRawArrayLibrary.h
to see what is available.
The raw array type is MRawArray
, which is a pointer, just like MTensor
.
Some notable differences from MTensor
s:
rawarray_t
is an enum for the different element types the raw array can hold (i.e. "Integer8"
, etc.)
We have MRawArray_getType
to get the type
We have a single void *MRawArray_getData(MRawArray)
function instead of different functions for each type.
There is a function for converting between raw arrays with different element types: MRawArray MRawArray_convertType(MRawArray, rawarray_t)
The type specification in LibraryFunctionLoad
is "RawArray"
, RawArray
or LibraryDataType[RawArray]
. It is not possible to restrict the element type or rank (or to request an automatic conversion to a certain element type), as is the case with packed arrays / MTensor
s.
LTemplate has experimental support for RawArray
though GenericRawArray
(unspecialized) and RawArrayRef<T>
(specialized for a type). Unlike plain LibraryLink, LTemplate allows explicit element type specifications for raw arrays (only for type checking, not auto-conversion).
Missing: How does MRawArray_convertType
compare to RawArrayConvert
and its third argument?
Image[ra, type]
can create an image from a raw array. The image type must be specified and it must be compatible with the element type of the raw array.
Audio[ra, ...]
can create an audio object from a RawArray of compatible type
RawArray["Byte", ba]
can create an "UnsignedInteger8"
-type raw array from the ByteArray
ba
.
MatrixForm/@Table[Normal[Developer`AllocateRawArray["Integer8",{3,3}]],10]
to produce a random matrix,but it is seem not very random?
$\endgroup$