Base class selection for generic code?

Issue #306 resolved
Daniel Baker created an issue

Hi,

I’ve been using your library for years and I’m quite pleased with it from most perspectives. I had one question, however; if I wanted to write software that works with both CustomMatrix, DynamicMatrix, and StaticMatrix, is there a type I can use as a base class so that the same code can work on all of them? I’ve tried inheriting from Matrix, and that hasn’t worked.

I’ve usually ended up just templating by class (template<typename MatType>), but it would be nice to be stricter about contained types and orientations so that fewer overloads need to be written. (Since different functions need to be written for differing transpose flags.)

This is mostly an issue of user ignorance of how the library works. Either way, I appreciate your time. Thanks!

Comments (3)

  1. Klaus Iglberger

    Hi Daniel!

    Thanks a lot for the positive feedback, that is very much appreciated 🙂

    There is indeed a base class that you can use to work with all kinds of dense matrices. In the wiki you’ll find the available base classes:

    template< typename VT  // Concrete type of the dense or sparse vector
            , bool TF >    // Transpose flag (blaze::columnVector or blaze::rowVector)
    class Vector;
    
    template< typename VT  // Concrete type of the dense vector
            , bool TF >    // Transpose flag (blaze::columnVector or blaze::rowVector)
    class DenseVector;
    
    template< typename VT  // Concrete type of the sparse vector
            , bool TF >    // Transpose flag (blaze::columnVector or blaze::rowVector)
    class SparseVector;
    
    template< typename MT  // Concrete type of the dense or sparse matrix
            , bool SO >    // Storage order (blaze::rowMajor or blaze::columnMajor)
    class Matrix;
    
    template< typename MT  // Concrete type of the dense matrix
            , bool SO >    // Storage order (blaze::rowMajor or blaze::columnMajor)
    class DenseMatrix;
    
    template< typename MT  // Concrete type of the sparse matrix
            , bool SO >    // Storage order (blaze::rowMajor or blaze::columnMajor)
    class SparseMatrix;
    

    All of these base classes are based on CRTP, i.e. the first template parameter is the dynamic type of the vector or matrix.

    Additionally you’ll find examples for how to use them. For instance, the following example shows the countZeros() function, which counts the number of values, which are exactly zero, in a dense, row-major matrix:

    template< typename MT >
    size_t countZeros( blaze::DenseMatrix<MT,rowMajor>& mat )
    {
       const size_t M( (~mat).rows() );
       const size_t N( (~mat).columns() );
       size_t count( 0UL );
    
       for( size_t i=0UL; i<M; ++i ) {
          for( size_t j=0UL; j<N; ++j ) {
             if( blaze::isDefault<strict>( (~mat)(i,j) ) )
                ++count;
          }
       }
    
       return count;
    }
    

    Note the use of the operator~(). By means of this operator you can cast back to the actual type of the dense matrix (e.g. StaticMatrix or DynamicMatrix). I hope this helps,

    Best regards,

    Klaus!

  2. Daniel Baker reporter

    Thank you! That should be sufficient. I very much appreciate the explanation and the example.

  3. Daniel Baker reporter

    The answer was promptly provided. I need no further help. This might be useful as an addendum to the documentation.

  4. Log in to comment