是否可以在不复制的情况下展平特征矩阵?

时间:2016-10-10 05:03:19

标签: c++ eigen

假设你有一个矩阵A

1 2
3 4

有两个扁平化:

1
2
3
4

1
3
2
4

如果使用默认(ColMajor)存储类型,我们可以将后者作为

VectorXd v = Map<const VectorXd>(A.data(), A.size())

这只会复制一次数据。

但要获得前者,我能想到的最好的是

MatrixXd At = A.transpose()
VectorXd v  = Map<const VectorXd>(At.data(), At.size())

不幸的是,这会复制数据两次。

有些令人困惑(至少对我而言)

VectorXd v  = Map<const VectorXd>(A.transpose().data(), A.size())

编译,但产生完全相同的结果,因为那里没有transpose

另请参阅:Eigen Convert Matrix to Vector

3 个答案:

答案 0 :(得分:1)

如果您愿意使用Matrix代替Vector,则可以使用以下内容:

Eigen::MatrixXi m(2, 2);
m << 1, 2, 3, 4;
std::cout << m << "\n\n";

// Option 1
Eigen::MatrixXi v1;
v1 = m.transpose();  // Copy #1
v1.resize(1, 4);  // No copy
std::cout << v1 << "\n\n";

// Option 2
v1 = m;  // Copy #1
v1.resize(1, 4);  // No copy
std::cout << v1 << "\n\n";

请注意,在某些情况下,使用1D矩阵时可能会遇到性能损失。

答案 1 :(得分:1)

请注意,您可以命名Map对象:

Map<const VectorXd> v1(A.data(), A.size());

并像v1一样使用VectorXd。当然,修改v1也会修改A。 要将其传递给接受const VectorXd&对象而无需复制的功能,请创建功能模板或制作Ref<const VectorXd>

然后第一种情况需要零拷贝,第二种情况需要转置拷贝。

答案 2 :(得分:0)

只需使用 Map API,以下是根据需要创建矩阵的一维线性视图的示例:

Eigen::MatrixXf M1(2,2); // Column-major storage    
M1 << 1, 2, 3, 4;

Eigen::Map<Eigen::RowVectorXf> v1(M1.data(), M1.size());
cout << "v1:" << endl << v1 << endl;

Eigen::Matrix<float,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> M2(M1);
Eigen::Map<Eigen::RowVectorXf> v2(M2.data(), M2.size());
std::cout << "v2:" << std::endl << v2 << std::endl;

输出:

v1:
1 3 2 4
v2:
1 2 3 4