Making the submatrix() function work for types which do not derive from DenseMatrix or SparseMatrix

Issue #299 wontfix
Mikhail Katliar created an issue

Let’s suppose I want to create a matrix class which does not inherit from DenseMatrix or SparseMatrix, but derives directly from Matrix:

template <typename T, bool SO>
class MyMatrix
:   public Matrix<MyMatrix, SO>
{
   // ...
};

I want to be able to use the submatrix() function provided by Blaze, which takes a Matrix<T, SO> argument. The following code

MyMatrix<double, rowMajor> A;
auto B = submatrix(A, 1, 1, 2, 2);

produces the compiler error:

[build] /usr/local/include/blaze/math/Aliases.h:270:1: error: incomplete type 'blaze::INVALID_TYPE' named in nested name specifier
[build] using OppositeType_t = typename T::OppositeType;
[build] ^~~~~
...

The reason is that the submatrix function returns an object of template class Submatrix, with one of the template parameters defining whether the matrix is a DenseMatrix or a SparseMatrix. It is currently not possible to return an object of different type from submatrix.

It may also be necessary to provide additional member function for submatrices of MyMatrix, which are not available in the blaze::Submatrix class. Therefore it is beneficial to have a mechanism to override the type of an object returned by the submatix function depending on the argument type.

Comments (2)

  1. Klaus Iglberger

    Hi Mikhail!

    As stated in the pull request, the idea to derive a matrix type directly from Matrix and not from DenseMatrix or SparseMatrix will not work well with the rest of the library. Thus it does not make sense from the point of view of Blaze and it is undesirable to adapt Blaze code for this case. A non-intrusive, easier alternative that leave you in full control over all details is based on function overloading:

    class MyMatrix
       : public Matrix< MyMatrix, rowMajor >
    {};
    
    inline decltype(auto)
       submatrix( MyMatrix& matrix, size_t row, size_t column, size_t m, size_t n )
    {
       // ...
       return MyMatrix{};
    }
    

    I hope this helps,

    Best regards,

    Klaus!

  2. Log in to comment