Empty static vectors and matrices

Issue #86 resolved
Mikhail Katliar created an issue

The following code produces compilation errors:

#include <blaze/Math.h>

using namespace blaze;

int main(int, char **)
{
    StaticVector<double, 0> v;  // <-- Compilation error
    StaticMatrix<double, 1, 0> m;   // <-- Compilation error

    return 0;
}

Compiler output:

/home/mkatliar/workspace/tmp/blaze_vector_of_size_0.cpp:7:29: error: aggregate ‘blaze::StaticVector<double, 0ul> v’ has incomplete type and cannot be defined
     StaticVector<double, 0> v;  // <-- Compilation error
                             ^
/home/mkatliar/workspace/tmp/blaze_vector_of_size_0.cpp:8:32: error: aggregate ‘blaze::StaticMatrix<double, 1ul, 0ul> m’ has incomplete type and cannot be defined
     StaticMatrix<double, 1, 0> m;   // <-- Compilation error
                                ^

Empty vectors and matrices are valid constructs and are sometimes necessary. Empty dynamic vectors and matrices are allowed in blaze, so probably empty static vectors and matrices should be allowed too.

Comments (6)

  1. Klaus Iglberger

    Hi Mikhail!

    Currently the instantiation of StaticVector and StaticMatrix with 0 is deliberately not allowed. This design decision is because we don't see any point in instantiating a compile time vector and/or matrix with a size of 0.

    In contrast to the static data structures, the dynamic versions can have a size of 0. For instance, in case of DynamicVector it is possible to set the size to 0. However, that is considered a valid and required state because this is the state of a default constructed DynamicVector or DynamicMatrix:

    DynamicVector<int> v;  // Default constructed vector of size 0
    DynamicMatrix<int> A;  // Default constructed 0x0 matrix
    

    Could you give us an example for a use case where a 0-dimensional StaticVector is required and beneficial? Thanks for raising this discussion,

    Best regards,

    Klaus!

  2. Mikhail Katliar reporter

    Hello Klaus,

    I am developing a library for model predictive control (MPC) and recently decided to switch from Eigen to blaze for matrix algebra. In MPC, systems have inputs, outputs and constraints. They are elements of vector spaces of respective dimensions NX, NU, NC. Vectors of sizes NX, NU, NC and matrices of sizes corresponding to different combinations of NX, NU, NC are used in calculations. For a given system, the dimensions are known at compile-time. Although in all practically interesting cases it holds NX>0 and NU>0, it is not uncommon to have NC=0. All the MPC algorithms retain their form when NC=0. If matrices and vectors with 0 dimensions are prohibited, it will require quite a lot of extra code to treat NC=0 as a special case. Therefore, having static vectors and matrices with some dimensions set to 0 would be very convenient.

    Best regards,

    Mikhail

  3. Klaus Iglberger

    The feature has been implemented and tested as required. It is immediately available via cloning the Blaze repository and will be officially released in Blaze 3.2.

    It is now possible to create instances of StaticVector and HybridVector with a compile time size of 0, and instances of StaticMatrix, and HybridMatrix with a compile time number of rows and/or columns of 0:

    StaticVector<int,0> a;  // StaticVector with size of 0
    HybridVector<int,0> b;  // HybridVector with maximum size of 0
    
    StaticMatrix<int,0,4> A;  // StaticMatrix with dimensions 0x4
    StaticMatrix<int,3,0> B;  // StaticMatrix with dimensions 3x0
    StaticMatrix<int,0,0> C;  // StaticMatrix with dimensions 3x4
    HybridMatrix<int,0,4> A;  // HybridMatrix with maximum dimensions 0x4
    HybridMatrix<int,3,0> B;  // HybridMatrix with maximum dimensions 3x0
    HybridMatrix<int,0,0> C;  // HybridMatrix with maximum dimensions 3x4
    

    Please note that it is not allowed to create static arrays of size 0 (C++14 standard, 8.3.4.1):

    ... If the constant-expression (5.19) is present, it shall be a converted constant expression of type std::size_t and its value shall be greater than zero.

    Therefore a vector with a compile time size of 0 or a matrix with 0 rows and/or columns will still allocate at least one element of the according data type.

  4. Log in to comment