0%

变形与切片

Eigen 尚未提供显式方法实现变形与切片,但可以用Map类模拟实现

变形

变形指的是在保持原有矩阵系数不变的情况下,调整矩阵的行列大小,Map类提供了一种在原有存储的基础上创建不同矩阵视图的方法,需要注意的是,原矩阵中的数据存储顺序会影响数据在线性视图中的顺序:

1
2
3
4
5
6
7
8
9
10
11
MatrixXf Ma(3,3);
M1 << 1,2,3,
4,5,6,
7,8,9;

Map<RowVectorXf> v1(M1.data(), M1.size()); // M1.data()将按列优先取出数据
cout << "v1:" << endl << v1 << endl;

Matrix<float, Dynamic, Dynamic, RowMajor> M2(M1);
Map<RowVectorXf> v2(M2.data(), M2.size()); // M2.data()将按行优先取出数据
cout << "v2:" << endl << v2 << endl;

输出:

1
2
3
4
v1:
1 4 7 2 5 8 3 6 9
v2:
1 2 3 4 5 6 7 8 9
  • 例:2 $\times$ 6 矩阵转置为6 $\times$ 2:
1
2
3
4
5
Matrix<float, Dynamic, Dynamic, RowMajor> M1(2,6);
M1 << 1,2,3, 4, 5, 6,
7,8,9,10,11,12;
Map<MatrixXf> M2(M1.data(), 6,2);
cout << "M2:" << endl << M2 << endl;

输出:

1
2
3
4
5
6
7
M2:
1 7
2 8
3 9
4 10
5 11
6 12

注意到实现矩阵转置的时候,必须采用行优先保存,否则变形出来的矩阵就不是转置矩阵了!

切片

切片指的是取出矩阵中均匀间隔的行、列或元素

  • 例:间隔取出向量中的某些元素
1
2
3
4
RowVectorXf v = RowVectorXf::LinSpaced(20,0,19);
cout << "Input:" << endl << v << endl;
Map<RowVectorXf,0,InnerStride<2> > v2(v.data(), v.size()/2);
cout << "Even:" << v2 << endl;

输出:

1
2
3
Input:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Even: 0 2 4 6 8 10 12 14 16 18
  • 例:根据具体的存储顺序,使用足够的步幅 stride 依次从三列中取出一列
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
MatrixXf M1 = MatrixXf::Random(3, 8);
cout << "Column Major Input:\n"
<< M1 << endl;

Map<MatrixXf, 0, OuterStride<>> M2(
M1.data(), M1.rows(), (M1.cols() + 2) / 3,
OuterStride<>(M1.outerStride() * 3));
// 第二个参数 MapOptions=0 即使用默认值Unaligned
// 第三个参数 OuterStride<>说明初始化时只需声明外步幅的大小
cout << "对列优先矩阵取出每3列中的第1列:\n"
<< M2 << endl;

typedef Matrix<float, Dynamic, Dynamic, RowMajor> RowMajorMatrixXf;
RowMajorMatrixXf M3(M1);
cout << "Row Major Input:\n"
<< M3 << endl;

Map<RowMajorMatrixXf, 0, Stride<Dynamic, 3>> M4(
M3.data(), M3.rows(), (M3.cols() + 2) / 3,
Stride<Dynamic, 3>(M3.outerStride(), 3)); // 意味着行间步幅1,列间步幅3
// 第三个参数 Stride<OuterStride<>, InnerStride<>> 指定外步幅和内步幅
cout << "对行优先矩阵取出每3列中的第1列:\n"
<< M4 << endl;

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Column Major Input:
0.680375 0.59688 -0.329554 0.10794 -0.270431 0.83239 -0.716795 -0.514226
-0.211234 0.823295 0.536459 -0.0452059 0.0268018 0.271423 0.213938 -0.725537
0.566198 -0.604897 -0.444451 0.257742 0.904459 0.434594 -0.967399 0.608353
对列优先矩阵取出每3列中的第1列:
0.680375 0.10794 -0.716795
-0.211234 -0.0452059 0.213938
0.566198 0.257742 -0.967399
Row Major Input:
0.680375 0.59688 -0.329554 0.10794 -0.270431 0.83239 -0.716795 -0.514226
-0.211234 0.823295 0.536459 -0.0452059 0.0268018 0.271423 0.213938 -0.725537
0.566198 -0.604897 -0.444451 0.257742 0.904459 0.434594 -0.967399 0.608353
对行优先矩阵取出每3列中的第1列:
0.680375 0.10794 -0.716795
-0.211234 -0.0452059 0.213938
0.566198 0.257742 -0.967399