Search code examples
c++eigeneigen3

Convert vector of dynamic Eigen vectors to bytes


I have a function to convert static Eigen vectors to a vector of bytes:

template<typename T, int N>
static std::vector<uint8_t> toBytes(std::vector<Eigen::Matrix<T, N, 1>> const & vectors)
{
    std::vector<uint8_t> bytes;
    uint8_t const * rawData = reinterpret_cast<uint8_t const *>(vectors.data());
    bytes.insert(bytes.end(), rawData, rawData + vectors.size() * N * sizeof(T));
    return bytes
}

This was sufficient until dynamic Eigen vectors showed up (i.e. Eigen::VectorXf), which have the N set to -1. So I came up with this:

template<typename T>
static std::vector<uint8_t> toBytes(std::vector<Eigen::Matrix<T, -1, 1>> const & vectors)
{
    std::vector<uint8_t> bytes;
    uint8_t const * rawData = reinterpret_cast<uint8_t const *>(vectors.data());
    bytes.insert(bytes.end(), rawData, rawData + vectors.size() * sizeof(vectors[0]));
    return bytes
}

This however results in a vector that is four times as big as expected, so I guess that dynamic vectors cannot not be trivially converted to bytes as a static vector. I can fix the size problem like this:

template<typename T>
static std::vector<uint8_t> toBytes(std::vector<Eigen::Matrix<T, -1, 1>> const & vectors)
{
    std::vector<uint8_t> bytes;
    uint8_t const * rawData = reinterpret_cast<uint8_t const *>(vectors.data());
    bytes.insert(bytes.end(), rawData, rawData + vectors.size() *  vectors[0].size() * sizeof(T));
    return bytes
}

This results in a vector of the correct length filled with values, but these values are not correct. How can I convert a vector of dynamic Eigen vectors to a vector of bytes?


Solution

  • Okay, there is one very obvious solution to this:

    template<typename T>
    static std::vector<uint8_t> createBuffer(std::vector<Eigen::Matrix<T, -1, 1>> const & vectors)
    {
        std::vector<uint8_t> & bytes = buffer.bytes;
        bytes.reserve(vectors.size() * vectors[0].size() * sizeof(T));
    
        for (auto const & vector : vectors)
        {
            for (int i = 0; i < vector.size(); ++i)
            {
                uint8_t const * rawData = reinterpret_cast<uint8_t const *>(&vector(0));
                bytes.insert(bytes.end(), rawData, rawData + sizeof(T));
            }
        }
    
        return bytes;
    }