Array
类提供了多用途的数组,这与专门为线性代数设计的Matrix
类相反,此外,Array
类提供了方便的元素级操作,这些操作不具线性代数的意义,比如为数组每个元素加上一个常数或对两个数组的对应元素进行相乘。
Content
1.Array Types
Array
是一个类模板,其模板参数与Matrix
类一致,前三个参数仍是必须的:
Array<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>
后三个参数是可选的,不做过多解释,参照Matrix
类即可。
Eigen也为一些常见的Array类型提供了简便的typedefs,与Matrix的typedefs相似,但稍微不同,因为Array
可同时用于一维、二维数组,因此我们规定ArrayNt
的形式代表一维数组,其中
N
、
t
N、t
N、t分别代表长度和数据类型,对于二维数组我们用ArrayNNt
,以下是一些例子:
typedef Array<float,Dynamic,1> ArrayXf
typedef Array<float,3,1> Array3f
typedef Array<double,Dynamic,Dynamic> ArrayXXd
typedef Array<double,3,3> Array33d
2.Accessing Values Inside An Array
与Matrix
类一致,括号运算符()
已经被重载,以对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
3.Addition And Subtraction
对两个数组进行的加减与对矩阵加减一致,只要两个数组尺寸一致,加减操作就是合法的,并且加减都是元素级的操作,会对数组对应位置的两个元素进行加减并得到新的数组。
数组同时支持如Array + Scalar
的形式,此操作会将标量与数组中的每个元素进行相加,这种功能在Matrix
类中并不能直接进行实现:
#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
4.Array Multiplication
首先,你完全可以使用标量与数组相乘,这与矩阵是一样的。但当你用数组与数组相乘时,Array
与Matrix
的区别就体现出来了:矩阵将乘法理解成矩阵乘法而数组将乘法理解成对应元素相乘,因此两个数组能够相乘的条件是它们有同样的大小:
#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
5.Other Coefficient-Wise Operations
除了上述提到的加、减、乘之外,Array
类还定义了其他元素级运算,如:.abs()
取每个元素的绝对值,.sqrt()
计算每个元素的平方根;如果有两个相同尺寸的数组,你还可以调用.min(.)
构造一个数组,数组中每个元素是所提供的两个数组中对应位置最小的那个元素:
#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 =
-2
-1.47
1.02
-0.165
0.131
a.abs() =
2
1.47
1.02
0.165
0.131
a.abs().sqrt() =
1.41
1.21
1.01
0.407
0.362
a.min(a.abs().sqrt()) =
-2
-1.47
1.01
-0.165
0.131
6.Converting Between Array And Matrix Expressions
Eigen不允许对数组进行矩阵操作,也不允许对矩阵进行数组操作,因此当你同时需要用到到两种操作时,你需要将一个矩阵转换成数组或将数组转换成矩阵,以下提供了一些方法使得两种类型的操作可以作用于同一个对象(不管将其声明为数组或是矩阵)。
Matrix
表达式中的.array()
方法可将矩阵‘转换’为数组,使得元素级操作变得简便;相反,Array
中的.matrix()
方法实现相反的‘转换’,.array()
与.matrix()
都能作为左值和右值。
官网废话太多了,总结几点:
- 可以将一个数组变量赋值给矩阵变量,反之亦然
- 矩阵元素级乘法除了用
.array()
转换为数组外还有const .cwiseProduct(.)
直接上例子:
MatrixXf m(2, 2);
MatrixXf n(2, 2);
// All Matrix and Array class variables can be assigned by Matrix or Array expression
// MatrixXf result(2, 2);
ArrayXXf 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
下面是一个更高级用法的例子(实际就是复合操作):
#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.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