2013-01-02 148 views
8

Eigen是一个众所周知的在C++中的矩阵库。我很难找到一个内置函数来简单地将一个项目推到矩阵的末尾。目前,我知道,它可以这样做:Eigen MatrixXd推回到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); 

,这将工作(一些语法可能是出于)。但它的一个简单的事情相当复杂。有没有内置函数?

回答

13

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

对于push_back函数,不要过于昂贵,它必须在空间用尽时按照某种因素增加矩阵的容量。然而,在处理矩阵时,内存使用通常是一个问题,因此矩阵的容量大于所需的容量可能会产生问题。 如果它将尺寸增加rows()cols(),则每次操作将为O(n*m)。这样做来填充整个矩阵将是O(n*n*m*m),即使是中等大小的矩阵也会很慢。

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

我能想到的,你不会不知道矩阵的大小的唯一情况是事先从文件中读取数据时。在这种情况下我要么使用push_back第一数据装入一个标准集装箱如std::vector然后将其复制到一个已经大小的矩阵,或者如果存储器是紧运行通过文件一次,以获得大小,然后进行第二次复制价值。

+1

好征,您可以在编译时定义MAXROWS MaxCols,所以即使你不知道确切的尺寸,直到运行时的内存需求保持有界(无内存分配将需要调整大小/的push_back操作)。如果您可以push_back元素,行和列的长度 gnzlbg

+1

“此外,在线性代数矩阵中,矢量大小几乎总是恒定的并且事先已知。”在大多数迭代算法中,您不知道需要多少次迭代才能满足收敛条件。 – Lindon

+0

上面的注意事项,如果我真的需要这个,我会分配一个大的矩阵,然后公开一个代表矩阵使用部分的块。推动,你填写存储矩阵的值,并创建一个新的扩展块,涵盖新的使用部分。当你耗尽存储矩阵的大小时,重新分配它使每个维度加倍。这是摊销常数,与std :: vector相同。一次可以将其作为自定义类来包装。 (我不知道与矩阵相比,块的特定限制,我只用了几次。) – THK

7

有没有这样的功能,但是,你可以建立这样的自己:

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

如果需要进行太多的调整大小,不过,这将是缓慢的窘况。