10

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);

这将起作用(某些语法可能已失效)。但是对于一件简单的事情来说,它非常复杂。是否已经有内置功能?

4

2 回答 2

17

特征矩阵没有这样的功能。这样做的原因是这样的函数要么非常慢,要么使用过多的内存。

为了使push_back函数不会过于昂贵,它必须像您所做的那样在空间不足时将矩阵的容量增加一些因素。但是,在处理矩阵时,内存使用通常是一个问题,因此矩阵的容量大于必要的容量可能会出现问题。如果它改为增加大小rows()cols()每次操作将是O(n*m). 这样做以填充整个矩阵O(n*n*m*m),即使是中等大小的矩阵也会非常慢。

此外,在线性代数中,矩阵和向量的大小几乎总是恒定的并且事先已知。通常在调整矩阵大小时,您并不关心矩阵中的先前值。这就是特征resize函数不保留旧值的原因,这与std::vector's不同resize

我能想到的唯一情况是您事先不知道矩阵的大小是从文件中读取时。在这种情况下,我会先将数据加载到标准容器中,例如std::vector使用push_back,然后将其复制到已经调整大小的矩阵中,或者如果内存很紧,则通过文件运行一次以获取大小,然后再次复制值.

于 2013-01-03T00:59:28.583 回答
11

没有这样的功能,但是,您可以自己构建类似的东西:

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;
}

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

于 2013-01-03T01:10:31.060 回答