c++中的特征矩阵推回

Eigen MatrixXd push back in c++

本文关键字:特征 c++      更新时间:2023-10-16

Eigen是c++中一个著名的矩阵库。我很难找到一个内置的功能,简单地把一个项目推到矩阵的末尾。目前我知道可以这样做:

Eigen::MatrixXd matrix(10, 3);
long int count = 0;
long int topCount = 10;
for (int i = 0; i < listLength; ++i) {
    matrix(count, 0) = list.x;
    matrix(count, 1) = list.y;
    matrix(count, 2) = list.z;
    count++;
    if (count == topCount) {
        topCount *= 2;
        matrix.conservativeResize(topCount, 3);
    }
}
matrix.conservativeResize(count, 3);

这将工作(一些语法可能是out)。但对于一件简单的事情来说,它相当复杂。是否已经有一个内置的功能?

对于特征矩阵不存在这样的函数。这样做的原因是这样的函数要么非常慢,要么使用过多的内存。

对于一个push_back函数来说,如果它不是非常昂贵,那么当它耗尽空间时,它必须像你所做的那样增加矩阵的容量。然而,在处理矩阵时,内存使用通常是一个问题,因此如果矩阵的容量大于必要的容量,可能会产生问题。如果每次增加rows()cols()的大小,则操作将是O(n*m)。这样做来填充整个矩阵将是O(n*n*m*m),即使是中等大小的矩阵也会相当慢。

此外,在线性代数中,矩阵和向量的大小几乎总是恒定的,并且事先已知。通常在调整矩阵的大小时,您并不关心矩阵中先前的值。这就是为什么Eigen的resize函数不保留旧值,不像std::vectorresize

我能想到的唯一一种你事先不知道矩阵大小的情况是从文件读取时。在这种情况下,我要么首先将数据加载到标准容器中,如使用push_backstd::vector,然后将其复制到已经大小的矩阵中,或者如果内存紧张,通过文件运行一次以获得大小,然后第二次复制值。

没有这样的函数,但是,您可以自己构建这样的函数:

using Eigen::MatrixXd;
using Eigen::Vector3d;
template <typename DynamicEigenMatrix>
void push_back(DynamicEigenMatrix& m, Vector3d&& values, std::size_t row)
{
    if(row >= m.rows()) {
        m.conservativeResize(row + 1, Eigen::NoChange);
    }
    m.row(row) = values;
}

int main()
{
    MatrixXd matrix(10, 3);
    for (std::size_t i = 0; i < 10; ++i) {
       push_back(matrix, Vector3d(1,2,3), i);
    }
    std::cout << matrix << "n";
    return 0;
}

如果这需要执行太多的大小调整,它将会非常慢。