Continuing our blog series "<a href="http://sandbox.arrayfire.com/tag/learning-arrayfire-from-scratch/">Learning ArrayFire from scratch</a>" today we will provide an introduction to the core data structure in ArrayFire: the af::array. We describe how to construct arrays, what datatypes arrays support, how to query an array for various properties (content, dimensions), how to write mathematical expressions on arrays.

<!--more-->

ArrayFire abstracts away much of the details of programming parallel architectures by providing a high-level container object, the <a class="el" href="classaf_1_1array.htm">array</a>, that represents data stored on a CPU, GPU, FPGA, or other type of accelerator. This abstraction permits developers to write massively parallel applications in a high-level language where they need not be concerned about low-level optimizations that are frequently required to achieve high throughput on most parallel architectures.
<h3>Creating ArrayFire Arrays</h3>
Arrays represent memory on a supported device. You can create arrays of uninitialized memory using the array constructor:
<pre class="lang:c++ decode:true">// Arrays may be created using the af::array constructor and dimensioned
// as 1D, 2D, 3D; however, the values in these arrays will be undefined
array undefined_1D = array(100);        // 1D array with 100 elements
array undefined_2D = array(10, 100);    // 2D array of size 10 x 100
array undefined_3D = array(10, 10, 10); // 3D array of size 10 x 10 x 10</pre>
Or using one of many constructors that initialize memory:
<pre class="lang:default decode:true">// Create an array of zeros of length three:
array zeros      = constant(0, 3);

// Generate a 1x4 array of uniformly distributed [0,1] random numbe// using af::randu():
array rand1      = randu(1, 4);
    
// Make a 2x2 array (or matrix, if you prefer) of random numbers
// sampled from a normal distribution using af::randn():
array rand2      = randn(2, 2);

// Construct a 3x3 identity matrix. 
array iden       = af::identity(3, 3);</pre>
Lastly, arrays may be populated with data from the host using our copy constructor:
<pre class="lang:default decode:true">// Create a six-element array on the host
float hA[] = {0, 1, 2, 3, 4, 5};
    
// Using the array copy constructor, we can create a 2x3
// matrix from this data:
array A(2, 3, hA);</pre>
Arrays can also be created from CUDA device pointers or OpenCL memory buffers. Please consult the <a href="http://arrayfire.org/docs/gettingstarted.htm">documentation</a> on these aspects.
<h3>Supported data types</h3>
ArrayFire arrays support standard integral and complex data types found in C/C++. The data type for an array is specified by providing an (optional) final parameter to any of the array constructors. The type field and supported types are as follows:
<ul>
 	<li>b8 8-bit boolean values (bool)</li>
 	<li>f32 real single-precision (float)</li>
 	<li>c32 complex single-precision (cfloat)</li>
 	<li>s32 32-bit signed integer (int)</li>
 	<li>u32 32-bit unsigned integer (unsigned)</li>
 	<li>f64 real double-precision (double)</li>
 	<li>c64 complex double-precision (cdouble)</li>
 	<li>s64 64-bit signed integer (intl)</li>
 	<li>u64 64-bit unsigned integer (uintl)</li>
 	<li>s16 16-bit signed integer (short)</li>
 	<li>u16 16-bit unsigned integer (unsigned short)</li>
</ul>
For example, if you wanted to construct a 2x1 (column vector) of uniformly distributed 32-bit complex numbers (c32 data type), you would use the following code:
<pre class="lang:default decode:true">// Create a 2x1 column vector of uniformly distributed
// 32-bit complex values:
array randcplx   = randu(2, 1, c32);</pre>
&nbsp;