参考:https://blog.csdn.net/whereismatrix/article/details/104400205?spm=1001.2014.3001.5501
简介
在Eigen内,有Matrix,vector进行线性代数的相关运算,但也需要执行对矩阵内的系数的相关操作时,这是正常的功能需求。Eigen
中的Array
类就是满足此需求的。
Array 定义
和前面介绍的Matrix和Vector类似,Array类也是一个模板类。
特殊一点的地方在于,Array
有一维数组,还有多维数组。
- 一维数组的便利简单名称采样形如:
ArrayNt
,这里N为该维度中数组大小,t为系数数据类型。 - 二维数组形如:
ArrayNNt
。
示例:
type | typedef |
---|---|
Array<float,Dynamic,1> | ArrayXf |
Array<float,3,1> | Array3f |
Array<double,Dynamic,Dynamic> | ArrayXXd |
Array<double,3,3> | Array33d |
对数组系数的访问及操作
如Matrix
中,重载的括号运算符()
用来访问数组中的系数,可以用来取值,也可以用于赋值。如代码中所看到的,还可以使用operator<<
来初始化一个数组。
示例:
// array_1.cpp
#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) = 1.1;
m(1,0) = 2.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 << 2.0,3.0,
8.0,9.0;
// print values to standard output
cout << m << endl;
}
执行:
$ g++ -I /usr/local/include/eigen3 array_1.cpp -o array_1
$ ./array_1
1 1.1
2 3.1
2 3
8 9
加法及减法运算
Array重载了operator +
, operator -
,可以对2个Array进行加法或减法运算,当然这2个array得有相同的Size,可很容易理解。
还重载实现了一种计算:array + scalar
。这会将标量加到每个数组元素上去。
示例:
// array_2.cpp
#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;
cout<<"array a:" << endl << a <<endl;
cout<<"array b:" << endl << b <<endl;
// array +/- array
cout << "a + b = " << endl << a + b << endl << endl;
// array - scalar
cout << "a - 1 = " << endl << a - 1 << endl;
}
执行:
$ g++ -I /usr/local/include/eigen3 array_2.cpp -o array_2
$
$ ./array_2
array a:
1 2 3
4 5 6
7 8 9
array b:
1 2 3
1 2 3
1 2 3
a + b =
2 4 6
5 7 9
8 10 12
a - 1 =
0 1 2
3 4 5
6 7 8
乘法运算
乘法分为两种: array * scalar
、 array * array
。其中 array * scalar
与matrix
一样;array * array
是面向数组系数的操作,对应匹配的系数进行相乘,只有2个具有相同维度的数组才能相乘。
示例:
//array_multi.cpp
#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<<"array a:" << endl << a <<endl;
cout<<"array b:" << endl << b <<endl;
cout << "a * b = " << endl << a * b << endl;
cout<< "a * 2 = " << endl << a * 2 << endl;
}
执行:
$ g++ -I /usr/local/include/eigen3 array_multi.cpp -o array_multi
$
$ ./array_multi
array a:
1 2
3 4
array b:
5 6
7 8
a * b =
5 12
21 32
a * 2 =
2 4
6 8
其他的面向系数的计算
针对array,除了上面提到的 +
, -
, *
的计算,这些都是面向数组系数的,还有其他的一些函数操作,比如:
abs()
方法返回数组每个元素的绝对值;sqrt()
方法计算每个元素的根;min(.)
:如果你有两个尺寸相同的数组,可以使用min()方法构建一个新的数组,新的数组的元素是原来的两个数组的对应位置的最小值。
示例:
//array_others.cpp
#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;
}
执行:
$ g++ -I /usr/local/include/eigen3 array_others.cpp -o array_other
$
$ ./array_other
a =
-1.99997
-1.47385
1.02242
-0.165399
0.131069
a.abs() =
1.99997
1.47385
1.02242
0.165399
0.131069
a.abs().sqrt() =
1.4142
1.21402
1.01115
0.406693
0.362034
a.min(a.abs().sqrt()) =
-1.99997
-1.47385
1.01115
-0.165399
0.131069
Array与Matrix直接转换
在Eigen内,Matrix
用于线性代理计算;而Array
用于针对系数进行操作,它们有不同的目的。
Matrix
类表达式expression 提供了.array()
函数方法,用于将矩阵matrix
转换成array
expression,然后就可以很容易对系数进行各种操作。对应地,Array
也提供了.matrix()
,用于从Array
得到一个matrix
expression表达式。
.array()
,.matrix()
既可以用于右值、也可以用于左值。但在一个表达式内,混合.array()
,.matrix()
是不可以的。比如,你不能直接让一个矩阵matrix
和数组array
相加。但可以通过.array()
,.matrix()
进行一下转换,再进行计算。
因为经常有这样的计算需求,Eigen中Matrix提供了一个便利函数cwiseProduct(Matrix)
,用于处理Matrix.array() * Matrix.array()
计算,即cwiseProduct()
方法进行矩阵间的元素级乘积(对应点相乘)。
示例:
//array_matrix_1.cpp
#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;
cout<<"array m:" << endl << m <<endl;
cout<<"array n:" << endl << n <<endl<<"-----------------"<< endl;
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;
}
执行:
$ g++ -I /usr/local/include/eigen3 array_matrix_1.cpp -o array_matrix_1
$
$ ./array_matrix_1
array m:
1 2
3 4
array n:
5 6
7 8
-----------------
-- 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