Table of Contents
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.
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);
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.
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.