![]() |
View on a specific submatrix of a dense or sparse matrix.The Submatrix class template represents a view on a specific submatrix of a dense or sparse matrix primitive. The type of the matrix is specified via the first template parameter: More...
#include <BaseTemplate.h>
View on a specific submatrix of a dense or sparse matrix.
The Submatrix class template represents a view on a specific submatrix of a dense or sparse matrix primitive. The type of the matrix is specified via the first template parameter:
A view on a dense or sparse submatrix can be created very conveniently via the submatrix()
function:
This 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. The view can also be used on both sides of an assignment: The submatrix can either be used as an alias to grant write access to a specific submatrix of a matrix primitive on the left-hand side of an assignment or to grant read-access to a specific submatrix of a matrix primitive or expression on the right-hand side of an assignment. The following example demonstrates this in detail:
A submatrix can be used like any other dense or sparse matrix. For instance, the elements of the submatrix can be directly accessed with the function call operator:
Alternatively, the elements of a submatrix can be traversed via (const) iterators. Just as with matrices, in case of non-const submatrices, begin()
and end()
return an Iterator, which allows a manipulation of the non-zero values, in case of constant submatrices a ConstIterator is returned:
Inserting/accessing elements in a sparse submatrix can be done by several alternative functions. The following example demonstrates all options:
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 submatrices are views on a specific submatrix of a matrix, several operations are not possible on views, such as resizing and swapping:
The following example gives an impression of the use of Submatrix 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:
Usually submatrices can be defined anywhere within a matrix. They may start at any position and may have an arbitrary extension (only restricted by the extension of the underlying matrix). However, in contrast to matrices themselves, which are always properly aligned in memory and therefore can provide maximum performance, this means that submatrices in general have to be considered to be unaligned. This can be made explicit by the blaze::unaligned flag:
All of these calls to the submatrix()
function are identical. Whether the alignment flag is explicitly specified or not, it always returns an unaligned submatrix. Whereas this may provide full flexibility in the creation of submatrices, this might result in performance restrictions (even in case the specified submatrix could be aligned). However, it is also possible to create aligned submatrices. Aligned submatrices are identical to unaligned submatrices in all aspects, except that they may pose additional alignment restrictions and therefore have less flexibility during creation, but don't suffer from performance penalties and provide the same performance as the underlying matrix. Aligned submatrices are created by explicitly specifying the blaze::aligned flag:
The alignment restrictions refer to system dependent address restrictions for the used element type and the available vectorization mode (SSE, AVX, ...). The following source code gives some examples for a double precision dense matrix, assuming that AVX is available, which packs 4 double
values into a SIMD vector:
Note that the discussed alignment restrictions are only valid for aligned dense submatrices. In contrast, aligned sparse submatrices at this time don't pose any additional restrictions. Therefore aligned and unaligned sparse submatrices are truly fully identical. Still, in case the blaze::aligned flag is specified during setup, an aligned submatrix is created:
It is also possible to create a submatrix view on another submatrix. In this context it is important to remember that the type returned by the submatrix()
function is the same type as the type of the given submatrix, since the view on a submatrix is just another view on the underlying dense matrix:
Submatrices can also be created on symmetric matrices (see the SymmetricMatrix class template):
It is important to note, however, that (compound) assignments to such submatrices have a special restriction: The symmetry of the underlying symmetric matrix must not be broken! Since the modification of element of a symmetric matrix also modifies the element
, the matrix to be assigned must be structured such that the symmetry of the symmetric matrix is preserved. Otherwise a std::invalid_argument exception is thrown: