Chapter IV.2. Arrays and geometries

Table of Contents

IV.2.1. Arrays basics
IV.2.1.1. Cartesian geometry
IV.2.1.2. Constructing an array
IV.2.2. Vector-valued arrays
IV.2.3. Zigzag arrays

The main classes in the SAL are array_view and array, with the latter deriving from the former. An array_view is a combination between two entities:

An array is just an array_view which is responsible for allocating and destroying its own data internally. Both array and array_view satisfy the requirements for being engines, which means that they can be stored in the nodes of a workspace.

IV.2.1. Arrays basics

IV.2.1.1. Cartesian geometry

We call 'Cartesian' an array whose elements are indexed by sequences of integers i0,i1,...,ir-1, where the length r of these sequences if called the rank of the array, and the integer ik is called the index in the (k+1)-th direction (or simply the (k+1)-th index). According to our convention, when traversing the elements according to the order in which they are stored in memory, the index in the first direction varies the fastest, then the second, etc, and the index along the last direction varies the slowest. For matrices, this correspond to so-called row-major ordering, and it is also the same convention used in Matlab and Fortran. Restricting ourselves for the moment to the case where the whole array is stored in local memory, the geometry of a Cartesian array is fully defined by a sequence of r unsigned integers called the domain of the array. The (k+1)-th integer Nk in the domain defines the range [[0,..,Nk-1]] in which the (k+1)-th index is allowed to vary.

Identifiers which are specific to Cartesian arrays are defined in the namespace cartesian. The class template cartesian::local_geometry takes two template arguments:

rank_t rank The rank of the array.
class Domain A Random Access Container type which will be used to store the domain of the array.

The Domain has a default type which is boost::array<size_t,rank>, and rarely needs to be specified explicitly.

To construct a 3D Cartesian geometry, one may proceed as follows:

						typedef cartesian::local_geometry<3> geometry_type;
						geometry_type::global_domain_type domain = {{32,64,64}};
						geometry_type g(domain); 
					

IV.2.1.2. Constructing an array

The geometry g defined above can in turn be used to construct a 3D array:

					typedef array<geometry_type> a(g);
				

Indeed, the class template array takes the following template arguments:

class Geometry The Geometry of the array.
class TElem The type of elements that will be stored in the array.

The default value for TElem is the macro SC_DEF_TELEM which is normally double but can be customized at compile-time using the precision feature when calling bjam: precision=32 corresponds to float, precision=64 (the default) corresponds to double, precision=128 corresponds to long double, and precision=arbitrary makes use of the GNU multiprecision library to provide arbirary precision floating point numbers.

The array construtor will take care of allocating the necessary memory, which will eventually get freed at the time of destruction. To prevent excessive memory allocation, array is inherits from boost::noncopyable, and therefore does not have an accessible copy constructor. Deep copies of array objects must be constructed manually by declaring another instance and using the member function copy. Shallow copies are handled by the array_view class template, and can be obtained by calling the member function view.

To use external memory management, array_view can also be instanciated directly. Its template parameters are the same as array, and its constructor takes as parameter a pair made of a geometry and a pointer to some sufficiently large memory space:

						double* data = new double[32*64*64];
						{
							array_view<geometry_type> a2(std::make_pair(g,data));
							/* ... */
						}
						delete[] data;
					

Of course, the user is then responsible for freeing the allocated memory after the destruction of the array_view object.

IV.2.2. Vector-valued arrays

Any C++ type, as long as it is default constructible and assignable, can be stored in spectral arrays. For convenience, KW defines the spectral::vec::vector class template, which is used to define vector-valued arrays:
			namespace vec {
				template<class TElem, unsigned int ncomponents>
				class vector;
			}
			
All the standard algebraic operations are defined for vectors in the namespace spectral::vec. For more details, see there.

IV.2.3. Zigzag arrays

In some applications, when simple cartesian arrays are used to store data, it appears that a very large number of elements are zero or close to zero. Such arrays are called sparse. To store them, it is much more efficient to use another data structure, which takes into account the sparsity. In KW, we have developed one such data structure, which we call zigzag arrays.