![]() |
Instantiating and setting up a vector is very easy and intuitive. However, there are a few rules to take care of:
The DynamicVector and CompressedVector classes offer a constructor that allows to immediately give the vector the required size. Whereas DynamicVector uses this information to allocate memory for all vector elements, CompressedVector merely acquires the size but remains empty.
All dense vector classes offer a constructor that allows for a direct, homogeneous initialization of all vector elements. In contrast, for sparse vectors the predicted number of non-zero elements can be specified
The StaticVector class offers a special initialization constructor. For StaticVectors of up to 6 elements (i.e. 6D vectors) the vector elements can be individually specified in the constructor:
Alternatively, all dense vector classes offer a constructor for an initialization with a dynamic or static array. If the vector is initialized from a dynamic array, the constructor expects the actual size of the array as first argument, the array as second argument. In case of a static array, the fixed size of the array is used:
All dense and sparse vectors can be created as the copy of any other dense or sparse vector with the same transpose flag (i.e. blaze::rowVector or blaze::columnVector).
Note that it is not possible to create a StaticVector as a copy of a vector with a different size:
There are several types of assignment to dense and sparse vectors: Homogeneous Assignment, Array Assignment, Copy Assignment, and Compound Assignment.
Sometimes it may be necessary to assign the same value to all elements of a dense vector. For this purpose, the assignment operator can be used:
Dense vectors can also be assigned a static array:
For all vector types it is generally possible to assign another vector with the same transpose flag (i.e. blaze::columnVector or blaze::rowVector). Note that in case of StaticVectors, the assigned vector is required to have the same size as the StaticVector since the size of a StaticVector cannot be adapted!
Next to plain assignment, it is also possible to use addition assignment, subtraction assignment, and multiplication assignment. Note however, that in contrast to plain assignment the size and the transpose flag of the vectors has be to equal in order to able to perform a compound assignment.
Via the size()
function, the current size of a vector can be queried:
Via the capacity()
function the internal capacity of a DynamicVector or CompressedVector can be queried. Note that the capacity of a vector doesn't have to be equal to the size of a vector. In case of a dense vector the capacity will always be greater or equal than the size of the vector, in case of a sparse vector the capacity may even be less than the size.
For both dense and sparse vectors the number of non-zero elements can be determined via the nonZeros()
function. Sparse vectors directly return their number of non-zero elements, dense vectors traverse their elements and count the number of non-zero elements.
The size of a StaticVector is fixed by the second template parameter. In contrast, the size of DynamicVectors as well as CompressedVectors can be changed via the resize()
function:
Note that resizing a vector invalidates all existing views (see e.g. Subvectors) on the vector:
When the internal capacity of a vector is no longer sufficient, the allocation of a larger junk of memory is triggered. In order to avoid frequent reallocations, the reserve()
function can be used up front to set the internal capacity:
Note that the size of the vector remains unchanged, but only the internal capacity is set according to the specified value!
The easiest and most intuitive way to access a dense or sparse vector is via the subscript operator. The indices to access a vector are zero-based:
Whereas using the subscript operator on a dense vector only accesses the already existing element, accessing an element of a sparse vector via the subscript operator potentially inserts the element into the vector and may therefore be more expensive. Consider the following example:
Although the compressed vector is only used for read access within the for loop, using the subscript operator temporarily inserts 10 non-zero elements into the vector. Therefore, all vectors (sparse as well as dense) offer an alternate way via the begin()
and end()
functions to traverse only the currently contained elements by iterators. In case of non-const vectors, begin()
and end()
return an Iterator, which allows a manipulation of the non-zero value, in case of a constant vector a ConstIterator is returned:
In contrast to dense vectors, that store all elements independent of their value and that offer direct access to all elements, spares vectors only store the non-zero elements contained in the vector. Therefore it is necessary to explicitly add elements to the vector. The first option to add elements to a sparse vector is the subscript operator:
In case the element at the given index is not yet contained in the vector, it is automatically inserted. Otherwise the old value is replaced by the new value 2. The operator returns a reference to the sparse vector element.
However, insertion of elements can be better controlled via the insert()
function. In contrast to the subscript operator it emits an exception in case the element is already contained in the matrix. In order to check for this case, the find()
function can be used:
Although the insert()
function is very flexible, due to performance reasons it is not suited for the setup of large sparse vectors. A very efficient, yet also very low-level way to fill a sparse vector is the append()
function. It requires the sparse vector to provide enough capacity to insert a new element. Additionally, the index of the new element must be larger than the index of the previous element. Violating these conditions results in undefined behavior!
In order to reset all elements of a vector, the reset()
function can be used:
In order to return a vector to its default state (i.e. the state of a default constructed vector), the clear()
function can be used:
Note that resetting or clearing both dense and sparse vectors does not change the capacity of the vectors.
As already mentioned, vectors can either be column vectors (blaze::columnVector) or row vectors (blaze::rowVector). A column vector cannot be assigned to a row vector and vice versa. However, vectors can be transposed via the trans()
function:
In order to calculate the length of a vector, both the length()
and sqrLength()
function can be used:
Note that both functions can only be used for vectors with built-in or complex element type!
The abs()
function can be used to compute the absolute values of each element of a vector. For instance, the following computation
results in the vector
The normalize()
function can be used to scale any non-zero vector to a length of 1. In case the vector does not contain a single non-zero element (i.e. is a zero vector), the normalize()
function returns a zero vector.
Note that the normalize()
function only works for floating point vectors. The attempt to use it for an integral vector results in a compile time error.
Via the swap()
function it is possible to completely swap the contents of two vectors of the same type: