Eigen學習筆記(4)-Array類和元素級操作

原文: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

參考:

“Eigen教程(4)”
“Eigen學習之Array類”

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章