Adaptors act as wrappers around the general Matrix Types. They adapt the interface of the matrices such that certain invariants are preserved. Due to this adaptors can provide a compile time guarantee of certain properties, which can be exploited for optimized performance.
The Blaze library provides a total of 9 different adaptors:
- Symmetric Matrices
- Hermitian Matrices
- Triangular Matrices
In combination with the general matrix types, Blaze provides a total of 40 different matrix types that make it possible to exactly adapt the type of matrix to every specific problem.
The following code examples give an impression on the use of adaptors. The first example shows the multiplication between two lower matrices:
using blaze::DynamicMatrix; using blaze::LowerMatrix; using blaze::rowMajor; using blaze::columnMajor; LowerMatrix< DynamicMatrix<double,rowMajor> > A; LowerMatrix< DynamicMatrix<double,columnMajor> > B; DynamicMatrix<double,columnMajor> C; // ... Resizing and initialization C = A * B;
When multiplying two matrices, at least one of which is triangular, Blaze can exploit the fact that either the lower or upper part of the matrix contains only default elements and restrict the algorithm to the non-zero elements. Thus the adaptor provides a significant performance advantage in comparison to a general matrix multiplication, especially for large matrices.
The second example shows the
SymmetricMatrix adaptor in a row-major dense matrix/sparse vector multiplication:
using blaze::DynamicMatrix; using blaze::DynamicVector; using blaze::CompressedVector; using blaze::rowMajor; using blaze::columnVector; SymmetricMatrix< DynamicMatrix<double,rowMajor> > A; CompressedVector<double,columnVector> x; DynamicVector<double,columnVector> y; // ... Resizing and initialization y = A * x;
In this example it is not intuitively apparent that using a row-major matrix is not the best possible choice in terms of performance since the computation cannot be vectorized. Choosing a column-major matrix instead, however, would enable a vectorized computation. Therefore Blaze exploits the fact that
A is symmetric, selects the best suited storage order and evaluates the multiplication as
y = trans( A ) * x;
which significantly increases the performance.