![]() |
Blaze 3.9
|
Row selections provide views on arbitrary compositions of rows of dense and sparse matrices. These views act as a reference to the selected rows and represent them as another dense or sparse matrix. This reference is valid and can be used in every way any other dense or sparse matrix can be used as long as the matrix containing the rows is not resized or entirely destroyed. The row selection also acts as an alias to the matrix elements in the specified range: Changes made to the rows (e.g. modifying values, inserting or erasing elements) are immediately visible in the matrix and changes made via the matrix are immediately visible in the rows.
A row selection can be created very conveniently via the rows()
function. It can be included via the header files
and forward declared via the header file
The indices of the rows to be selected can be specified either at compile time or at runtime (by means of an initializer list, array or vector):
Note that it is possible to alias the rows of the underlying matrix in any order. Also note that it is possible to use the same index multiple times.
Alternatively it is possible to pass a callable such as a lambda or functor that produces the indices:
The rows()
function returns an expression representing the view on the selected rows. The type of this expression depends on the given arguments, primarily the type of the matrix and the compile time arguments. If the type is required, it can be determined via the decltype
specifier:
The resulting view can be treated as any other dense or sparse matrix, i.e. it can be assigned to, it can be copied from, and it can be used in arithmetic operations. Note, however, that a row selection will always be treated as a row-major matrix, regardless of the storage order of the matrix containing the rows. The view can also be used on both sides of an assignment: It can either be used as an alias to grant write access to specific rows of a matrix primitive on the left-hand side of an assignment or to grant read-access to specific rows of a matrix primitive or expression on the right-hand side of an assignment. The following example demonstrates this in detail:
The elements of a row selection can be directly accessed via the function call operator:
Alternatively, the elements of a row selection can be traversed via (const) iterators. Just as with matrices, in case of non-const row selection, begin()
and end()
return an iterator, which allows to manipuate the elements, in case of constant row selection an iterator to immutable elements is returned:
Inserting/accessing elements in a sparse row selection can be done by several alternative functions. The following example demonstrates all options:
A view on specific rows of a matrix can be used like any other dense or sparse matrix. For instance, the current size of the matrix, i.e. the number of rows or columns can be obtained via the rows()
and columns()
functions, the current total capacity via the capacity()
function, and the number of non-zero elements via the nonZeros()
function. However, since row selections are views on specific rows of a matrix, several operations are not possible, such as resizing and swapping:
Both dense and sparse row selections can be used in all arithmetic operations that any other dense or sparse matrix can be used in. The following example gives an impression of the use of dense row selctions within arithmetic operations. All operations (addition, subtraction, multiplication, scaling, ...) can be performed on all possible combinations of dense and sparse matrices with fitting element types:
Especially noteworthy is that row selections can be created for both row-major and column-major matrices. Whereas the interface of a row-major matrix only allows to traverse a row directly and the interface of a column-major matrix only allows to traverse a column, via views it is possible to traverse a row of a column-major matrix or a column of a row-major matrix. For instance:
However, please note that creating a row selection on a matrix stored in a column-major fashion can result in a considerable performance decrease in comparison to a row selection on a matrix with row-major storage format. This is due to the non-contiguous storage of the matrix elements. Therefore care has to be taken in the choice of the most suitable storage order:
Although Blaze performs the resulting matrix/matrix multiplication as efficiently as possible using a row-major storage order for matrix A
would result in a more efficient evaluation.