原文:Eigen官网-The Array class and coefficient-wise operations
1. 引言
相对于Matrix提供的线性代数运算,Array类提供了更为一般的数组功能。Array类为元素级的操作提供了有效途径,比如点加(每个元素加值)或两个数据相应元素的点乘。且Array和Matrix之间很容易相互转换,所以相当于给矩阵提供更多的方法。也为使用者的不同需求提供了更多的选择。
2. Array的类型
Array是个类模板,Array类和Matrix有相同的参数。前三个参数是必须指定的,后三个是可选的。
Array<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>
Eigen也提供了一些常用Array类的定义,Array是同时支持一维和二维的(Matrix二维,Vector一维)。我们用ArrayNt
表示1维的array,其中N
表示大小,t
表示类型;用ArrayNNt
表示2维的array。
Type | Typedef |
---|---|
Array<float,Dynamic,1> | ArrayXf |
Array<float,3,1> | Array3f |
Array<double,Dynamic,Dynamic> | ArrayXXd |
Array<double,3,3> | Array33d |
3. 访问 Array中元素
圆括号 ( )
被重载用来访问Array中的元素(包括读和写)。另外,<<
可以用来初始化array(通过逗号初始化)或者用来打印array。
示例如下:
#include <Eigen/Dense>
#include <iostream>
using namespace Eigen;
using namespace std;
int main()
{
ArrayXXf m(2,2);
// assign some values coefficient by coefficient
m(0,0) = 1.0; m(0,1) = 2.0;
m(1,0) = 3.0; m(1,1) = m(0,1) + m(1,0);
// print values to standard output
cout << m << endl << endl;
// using the comma-initializer is also allowed
m << 1.0,2.0,
3.0,4.0;
// print values to standard output
cout << m << endl;
}
结果如下:
1 2
3 5
1 2
3 4
4. 加法和减法
对两个Array进行加法和减法是和Matrix一样,这个操作只要两个Array维度相同,元素类型相同就可以操作,实现对array中对应逐元素的相加和相减操作。
同时Array还定义了Matrix不支持的array + scalar
的操作,即将array中的每个元素都加上标量的值。
示例如下:
#include <Eigen/Dense>
#include <iostream>
using namespace Eigen;
using namespace std;
int main()
{
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;
// Adding two arrays
cout << "a + b = " << endl << a + b << endl << endl;
// Subtracting a scalar from an array
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
5. 乘法
对于一个Array和标量进行乘法操作是和Matrix一样的,同时Array也定义了两个Array之间的乘法操作,就是将两个Array的对应元素相乘,因此两个array必须具有相同的尺寸。
示例如下:
#include <Eigen/Dense>
#include <iostream>
using namespace Eigen;
using namespace std;
int main()
{
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
6. 其他的元素级操作
methods | functions |
---|---|
.abs() | 计算每个元素的绝对值 |
.sqrt() | 计算每个元素的平方根 |
.min(.) | 对于两个具有相同大小的矩阵,选取对应位置的较小元素重新生成一个array |
示例如下:
#include <Eigen/Dense>
#include <iostream>
using namespace Eigen;
using namespace std;
int main()
{
ArrayXf a = ArrayXf::Random(5);
a *= 2;
cout << "a =" << endl
<< a << endl;
cout << "a.abs() =" << endl
<< a.abs() << endl;
cout << "a.abs().sqrt() =" << endl
<< a.abs().sqrt() << endl;
cout << "a.min(a.abs().sqrt()) =" << endl
<< a.min(a.abs().sqrt()) << endl;
}
结果如下:
a =
1.36
-0.422
1.13
1.19
1.65
a.abs() =
1.36
0.422
1.13
1.19
1.65
a.abs().sqrt() =
1.17
0.65
1.06
1.09
1.28
a.min(a.abs().sqrt()) =
1.17
-0.422
1.06
1.09
1.28
7. array和matrix之间的相互转换
你应该什么时候使用Matrix类的对象,什么时候使用Array类的对象呢?当你需要使用线性代数运算时就应该使用matrix,而当你需要使用元素级的操作时,就需要使用array。
Matrix类有.array()
方法,用于将matrix转换为array。
Array类有matrix()
方法,用于将array转换成matrix。
在Eigen,在表达式中混合Matrix和Array操作是被禁止的,但是可以将array表达式结果赋值为matrix。
Eigen提供了.const.cwiseProduct(.)
方法用于实现matrix之间的逐元素相乘操作。
示例如下:
#include <Eigen/Dense>
#include <iostream>
using namespace Eigen;
using namespace std;
int main()
{
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