Clone wiki

blaze / Block Vectors and Matrices


General Concepts

In addition to fundamental element types, the Blaze library supports vectors and matrices with non-fundamental element type. For instance, it is possible to define block matrices by using a matrix type as the element type:

using blaze::DynamicMatrix;
using blaze::DynamicVector;
using blaze::rowMajor;
using blaze::columnVector;

DynamicMatrix< DynamicMatrix<double,rowMajor>, rowMajor > A;
DynamicVector< DynamicVector<double,columnVector >, columnVector > x, y;

// ... Resizing and initialization

y = A * x;

The matrix/vector multiplication in this example runs fully parallel and uses vectorization for every inner matrix/vector multiplication and vector addition.


Pitfalls

The only thing to keep in mind when using non-fundamental element types is that all operations between the elements have to be well defined. More specifically, the size of vector and matrix elements has to match. The attempt to combine two non-matching elements results in either a compilation error (in case of statically sized elements) or an exception (for dynamically sized elements):

DynamicVector< StaticVector<int,2UL> > a;
DynamicVector< StaticVector<int,3UL> > b;

DynamicVector< DynamicVector<int> > c( a + b );  // Compilation error: element size doesn't match

Therefore please don't forget that dynamically sized elements (e.g. blaze::DynamicVector, blaze::HybridVector, blaze::DynamicMatrix, blaze::HybridMatrix, ...) need to be sized accordingly upfront.


Examples

The first example demonstrates the multiplication between a statically sized block matrix and a block vector:

using namespace blaze;

// ( ( 1 1 )  ( 2 2 ) )   ( ( 1 ) )   ( ( 10 ) )
// ( ( 1 1 )  ( 2 2 ) )   ( ( 1 ) )   ( ( 10 ) )
// (                  ) * (       ) = (        )
// ( ( 3 3 )  ( 4 4 ) )   ( ( 2 ) )   ( ( 22 ) )
// ( ( 3 3 )  ( 4 4 ) )   ( ( 2 ) )   ( ( 22 ) )

using M2x2 = StaticMatrix<int,2UL,2UL,rowMajor>;
using V2   = StaticVector<int,2UL,columnVector>;

DynamicMatrix<M2x2,rowMajor> A{ { M2x2(1), M2x2(2) },
                                { M2x2(3), M2x2(4) } };

DynamicVector<V2,columnVector> x{ V2(1), V2(2) };

DynamicVector<V2,columnVector> y( A * x );

The second example shows the multiplication between a compressed block matrix with blocks of varying size and a compressed block vector:

using namespace blaze;

// ( ( 1 -2  3 )         ( 5 -1 ) )   ( (  1 ) )   ( ( -3 ) )
// ( ( 4  1  0 )         ( 1  2 ) )   ( (  0 ) )   ( (  7 ) )
// ( ( 0  2  4 )         ( 3  1 ) )   ( (  1 ) )   ( (  3 ) )
// (                              )   (        )   (        )
// (              ( 1 )           ) * ( (  2 ) ) = ( (  2 ) )
// (                              )   (        )   (        )
// ( ( 0 -1  1 )         ( 1  0 ) )   ( ( -1 ) )   ( (  0 ) )
// ( ( 2 -1  2 )         ( 0  1 ) )   ( (  2 ) )   ( (  6 ) )

using M3x3 = HybridMatrix<int,3UL,3UL,rowMajor>;
using V3   = HybridVector<int,3UL,columnVector>;

CompressedMatrix<M3x3,rowMajor> A( 3UL, 3UL, 5UL );
A(0,0) = M3x3{ { 1, -2, 3 }, { 4, 1, 0 }, { 0, 2, 4 } };
A(0,2) = M3x3{ { 5, -1 }, { 1, 2 }, { 3, 1 } };
A(1,1) = M3x3{ { 1 } };
A(2,0) = M3x3{ { 0, -1, 1 }, { 2, -1, 2 } };
A(2,2) = M3x3{ { 1, 0 }, { 0, 1 } };

CompressedVector<V3,columnVector> x( 3UL, 3UL );
x[0] = V3{ 1, 0, 1 };
x[1] = V3{ 2 };
x[2] = V3{ -1, 2 };

CompressedVector<V3,columnVector> y( A * x );

Previous: LAPACK Functions ---- Next: Intra-Statement Optimization

Updated