在实际工程中,往往还需要依赖其它库的数据接口,Eigen设计了Map来解决这一问题。
C数组转换为Matrix
Map要求传入一个存储数据的地址,无论是固定大小的矩阵还是动态大小的矩阵,这个参数是必不可少的。第4行中array是一个const类型的指针,代表数据存储的地址。如果要将第三方数据映射成固定大小的矩阵,Map初始化构造函数可以不指定矩阵的维度,如第4行。如果映射成动态大小的矩阵,必须在Map初始化构造函数中指明矩阵大小,如第8行。有时,为了避免对原始数据的修改,需要将映射申明为const,如第14行定义的Map对象c就不容许对原始数组进行修改。
1. TEST(MapInterFace, ReadFromArray)
2. {
3. int array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
4. Map<Matrix<int, 2, 5>> a(array);
5. a(0, 0) = 1111;
6. cout << "Here is array\n"
7. << a << endl;
8. Map<VectorXi> b(array, 3);
9. cout << "Here is b(array, 3)\n"
10. << b << endl;
11. cout << "Here is b.norm()\n"
12. << b.norm() << endl;
13. // 加const修饰,避免对原始数据的修改
14. Map<const Matrix<int, 2, 5>> c(array);
15. cout << c << endl;
16. }
Map允许一个对象在映射了数据之后重新映射数据,只需要调用new操作符即可new (&a) Map(array + 2, 5),代码中a在重新映射数据之前已经映射了数据。
Matrix转换为C数组
那么如何将一个Eigen矩阵转换为C数组呢?最直接的方式是使用for循环逐个读取矩阵里面的元素。事实上Eigen有提供接口专门用于实现这种转换,这个接口是matrix.data()。如下图所示的代码就可以将Eigen矩阵转换为数组。
1. TEST(MapInterFace, Matrix2Array)
2. {
3. Matrix3f a{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
4. cout << "Here is Matrix3f a\n"
5. << a << endl;
6.
7. const float *cArray = a.data();
8. cout << "C Array:" << endl;
9. for (int i = 0; i < a.size(); ++i)
10. {
11. cout << cArray[i] << " ";
12. }
13. cout << endl;
14. }