Eigen库学习 ---- 3.数组类和系数运算
上篇:Eigen库学习 ---- 2.矩阵\向量的算数运算
本篇为这个链接的学习总结。
Array类提供通用数组,而Matrix类则用于线性代数。此外,Array类提供了一种执行按系数运算的简单方法,这种方法可能没有线性代数意义,例如向数组中每个系数添加一个常量或者按系数将两个数组相乘。
一、数组类
数组是采用与矩阵相同的类模板,与矩阵一样,前三个模板参数是必须的。
Array<typename Scalar, int Rows, int Cols>
即:
Array <元素类型例如float型, int 行, int 列>
Eigen提供了一些常用的typedef(类似于矩阵的typedef)。array可表示一位数组和二维数组,我们采用的惯例是,ArrayNt形式的typedef表示一位数组,其中N和t是大小和标量类型。对于二维数组,我们使用ArrayNNt形式的typedef。
例如:
二、访问数组元素
访问元素和矩阵类类似,如下例程:
ArrayXXf m(2, 2);
//为数组分配数据
m(0, 0) = 1.0; m(0, 1) = 2.0;
m(1, 0) = 3.0; m(1, 1) = m(0, 1)+ m(1, 0);
//打印数据
cout << m << endl << endl;
//下面这种方式也是可以的
m << 1.0, 2.0,
3.0, 4.0;
//打印数据
cout << m << endl;
三、数组加减法
两个数组的加法和减法与矩阵的加减法相同,需要保证两个数组的大小维度相同。数组还支持与标量的运算,这是矩阵所不能进行的。如下面例程,计算量两个相同的数组的运算和数组与标量的运算。
ArrayXXf a(3, 3);
ArrayXXf b(3, 3);
a << 1, 2, 3,
4, 5, 6,
7, 8, 9;
b << 1, 2, 3,
1, 2, 3,
1, 2, 3;
//两个数组运算
cout << "a+b=" << endl << a + b << endl << endl;
//数组与标量运算
cout << "a-2=" << endl << a - 2 << endl;
输出结果如下:
a+b=
2 4 6
5 7 9
8 10 12
a-2=
-1 0 1
2 3 4
5 6 7
四、数组乘法
数组可以与一个标量相乘,这个结果和矩阵与标量相乘的结果相同,就是将每一个元素对应乘这个标量。数组与数组相乘时和矩阵运算不同,数组乘数组是将对应的元素相乘。如下面例程:.
ArrayXXf a(2, 2);
ArrayXXf b(2, 2);
a << 1, 2,
3, 4;
b << 5, 6,
7, 8;
cout << "a*b=" << endl << a * b << endl;
输出结果如下:
a*b=
5 12
21 32
五、数组其他运算
数组的其他运算也都是元素级别的,是针对的每个元组进行操作。比如绝对值.abs(),开平方.sqrt(),最小值.min(.)等等,见下面例程:
ArrayXf a = ArrayXf::Random(5);
a *= 2;
cout << "a=" << endl << a << endl<<endl;
cout << "a.abs()=" << endl << a.abs() << endl << endl;
cout << "a.abs().sqrt()=" << endl << a.abs().sqrt() << endl << endl;
//下面是比较原数组a和新的数组a.abs().sqrt()中比较小的元素返回
cout << "a.min(a.abs().sqrt())=" << endl << a.min(a.abs().sqrt()) << endl;
输出结果如下:
a=
-1.99499
0.254341
-1.22678
1.23496
0.340037
a.abs()=
1.99499
0.254341
1.22678
1.23496
0.340037
a.abs().sqrt()=
1.41244
0.504323
1.1076
1.11129
0.583127
a.min(a.abs().sqrt())=
-1.99499
0.254341
-1.22678
1.11129
0.340037
六、数组类和矩阵类的相互转换
什么时候用矩阵类,什么时候用数组类呢?
我们不能将矩阵类的方法应用到数组类上,也不能将数组类的方法应用到矩阵类上。
因此,
如果需要线性代数相关的运算,就应该用矩阵类,
如果只是需要元素级别的操作,那就用数组类。
但是有时候,我们既需要使用矩阵类,也需要使用数组类,
那就需要矩阵\数组类的转换。
矩阵类有一个方法.array(),可以将矩阵类转化成数组类。
数组类有一个方法.matrix(),可以将数组类转化成矩阵类。
禁止在表达是中混用矩阵类和数组类,比如不能用+来连接数组和矩阵。但是=是例外,比如可以将矩阵的值赋值给数组,或者将数组的值赋值给矩阵。
由于数组的运算比较常见,所以在矩阵类的运算中提供了直接转化成数组类运算的方法.cwiseProduct(.),详细内容见下面例程:
MatrixXf m(2, 2);
MatrixXf n(2, 2);
MatrixXf result(2, 2);
m << 1, 2,
3, 4;
n << 5, 6,
7, 8;
result = m * n;
cout << "-- Matrix m*n: --" << endl << result << endl << endl;
result = m.array() * n.array();
cout << "-- Array m*n: --" << endl << result << endl << endl;
result = m.cwiseProduct(n);
cout << "-- With cwiseProduct: --" << endl << result << endl << endl;
result = m.array() + 4;
cout << "-- Array m + 4: --" << endl << result << endl << endl;
输出结果如下:
-- Matrix m*n: --
19 22
43 50
-- Array m*n: --
5 12
21 32
-- With cwiseProduct: --
5 12
21 32
-- Array m + 4: --
5 6
7 8
还有一个重要的例子,表达式(m.array() + 4).matrix() * m将矩阵m中的每一个元素+4,然后计算结果与m的矩阵。类似的,(m.array() * n.array()).matrix() * m计算矩阵m和n的各个元素的积,然后计算结果与矩阵m的矩阵积。例如:
MatrixXf m(2, 2);
MatrixXf n(2, 2);
MatrixXf result(2, 2);
m << 1, 2,
3, 4;
n << 5, 6,
7, 8;
result = (m.array() + 4).matrix() * m;
cout << "-- Combination 1: --" << endl << result << endl << endl;
result = (m.array() * n.array()).matrix() * m;
cout << "-- Combination 2: --" << endl << result << endl << endl;
输出结果如下:
-- Combination 1: --
23 34
31 46
-- Combination 2: --
41 58
117 170