假设你有一个矩阵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
。
答案 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