簡介
這裏將討論一下高級些的矩陣初始化方法。
comma-initializer
逗號初始化器 comma-initializer
方法很簡單,可以一下把矩陣/向量的係數全部設置完。語法很簡單,使用逗號分隔每個係數。前面的介紹文檔中已經多次使用了。只是要求在前面定義對象時,要知道矩陣/向量的維度和大小,賦值時注意數量要匹配。
而且,在初始化時,逗號分隔的對象可以時矩陣或者向量。
結合前面介紹的各種操作,綜合示例:
//matrix_initial1.cpp
#include <Eigen/Dense>
#include <iostream>
using namespace std;
using namespace Eigen;
int main()
{
RowVectorXd vec1(3);
vec1 << 1, 2, 3;
cout << "vec1 = " << vec1 << endl;
RowVectorXd vec2(4);
vec2 << 1, 4, 9, 16;
cout << "vec2 = " << vec2 << endl;
RowVectorXd joined(7);
joined << vec1, vec2;
cout << "joined = " << joined << endl;
cout << "-----------------------" << endl;
MatrixXf m(3,3);
m << 1,2,3,
4,5,6,
7,8,9;
cout << "Here is the initialed matrix m:" << endl << m << endl;
//
Matrix3f mf;
mf.row(0) << 1, 2, 3;
mf.block(1,0,2,2) << 4, 5, 7, 8;
mf.col(2).tail(2) << 6, 9;
cout << "Here is the other initialed matrix mf:" << endl << mf << endl;
}
執行:
$ g++ -I /usr/local/include/eigen3 matrix_initial1.cpp -o matrix_initial1
$
$ ./matrix_initial1
vec1 = 1 2 3
vec2 = 1 4 9 16
joined = 1 2 3 1 4 9 16
-----------------------
Here is the initialed matrix m:
1 2 3
4 5 6
7 8 9
Here is the other initialed matrix mf:
1 2 3
4 5 6
7 8 9
特別的矩陣和數組
Zero
Eigen內的Matrix和Array類有一些特殊的方法,比如Zero(),可以把所有的係數初始化爲0。
zero方法有3中變體:
- 對固定尺寸大小的對象:不需要參數,如直接
Array33f a = matrix3f.Zero();
- 對動態尺寸大小的一維對象:需要一個參數。如
ArrayXf a = ArrayXf::Zero(3);
- 對動態尺寸大小的二維對象: 需要2個參數。如
ArrayXXf a = ArrayXXf::Zero(3, 4);
Constant & Random
類似於zero,靜態static方法Constant(value)將把所有的係數設置爲指定的value值。如果要指定尺寸大小,則使用MatrixXd::Constant(rows, cols, value).
初始化時指定尺寸。
而Random會將對象填充隨機值。
單位矩陣Identity & LinSpaced
單位矩陣,顧名思義,只是產生矩陣的。
而 LinSpaced(size, low, high) ,只用於向量vector或者一維的Array數組。它會使用low到high之間的值,按照size,平均數值間距,得到各個係數,創建向量/數組。
其他輔助方法
Eigen定義了輔助方法,用於上述的方法的對應方法: setZero(), MatrixBase::setIdentity() and DenseBase::setLinSpaced() to do this conveniently.
。
示例
請參考示例。
//matrix_initial3.cpp
#include <Eigen/Dense>
#include <iostream>
using namespace std;
using namespace Eigen;
int main()
{
//
ArrayXXf table(10, 4);
table.col(0) = ArrayXf::LinSpaced(10, 0, 99);
table.col(1) = M_PI / 180 * table.col(0);
table.col(2) = table.col(1).sin();
table.col(3) = table.col(1).cos();
cout << " Degrees Radians Sine Cosine\n";
cout << table << endl;
//
cout << "-------------------------------" << endl;
// 快捷方法
const int size = 6;
MatrixXd mat1(size, size);
mat1.topLeftCorner(size/2, size/2) = MatrixXd::Zero(size/2, size/2);
mat1.topRightCorner(size/2, size/2) = MatrixXd::Identity(size/2, size/2);
mat1.bottomLeftCorner(size/2, size/2) = MatrixXd::Identity(size/2, size/2);
mat1.bottomRightCorner(size/2, size/2) = MatrixXd::Zero(size/2, size/2);
cout << " mat1 "<< endl;
cout << mat1 << endl << endl;
// 輔助方法
MatrixXd mat2(size, size);
mat2.topLeftCorner(size/2, size/2).setZero();
mat2.topRightCorner(size/2, size/2).setIdentity();
mat2.bottomLeftCorner(size/2, size/2).setIdentity();
mat2.bottomRightCorner(size/2, size/2).setZero();
cout << " mat2 "<< endl;
cout << mat2 << endl << endl;
//
MatrixXd mat3(size, size);
mat3 << MatrixXd::Zero(size/2, size/2), MatrixXd::Identity(size/2, size/2),
MatrixXd::Identity(size/2, size/2), MatrixXd::Zero(size/2, size/2);
cout << " mat3 "<< endl;
cout << mat3 << endl;
}
執行結果:
$ g++ -I /usr/local/include/eigen3 matrix_initial3.cpp -o matrix_initial3
$
$ ./matrix_initial3
Degrees Radians Sine Cosine
0 0 0 1
11 0.191986 0.190809 0.981627
22 0.383972 0.374607 0.927184
33 0.575959 0.544639 0.838671
44 0.767945 0.694658 0.71934
55 0.959931 0.819152 0.573576
66 1.15192 0.913545 0.406737
77 1.3439 0.97437 0.224951
88 1.53589 0.999391 0.0348995
99 1.72788 0.987688 -0.156434
-------------------------------
mat1
0 0 0 1 0 0
0 0 0 0 1 0
0 0 0 0 0 1
1 0 0 0 0 0
0 1 0 0 0 0
0 0 1 0 0 0
mat2
0 0 0 1 0 0
0 0 0 0 1 0
0 0 0 0 0 1
1 0 0 0 0 0
0 1 0 0 0 0
0 0 1 0 0 0
mat3
0 0 0 1 0 0
0 0 0 0 1 0
0 0 0 0 0 1
1 0 0 0 0 0
0 1 0 0 0 0
0 0 1 0 0 0
臨時對象及Finish()
在上面的示例,Zero() , Constant()
可以在聲明一個便利時,初始化對象; 也可以作爲右值用來做賦值操作。看起來,好像它們會返回一個對象(矩陣或者數組)。但實際上,它們返回的是一個表達式對象(expression object),然後在需要時,纔會對該表達式進行求值。這樣對性能不會產生什麼不好的影響。在前面的示例中,也有這樣的情況。
比如代碼:
MatrixXd m = MatrixXd::Random(3,3);
m = (m + MatrixXd::Constant(3,3,1.2))*10;
代碼中的m + MatrixXd::Constant(3,3,1.2)
,創建了一個3X3的,係數都爲1.2的常量矩陣,這時爲express-object
,在和m進行矩陣加法運算時,纔會真正求職計算。
而下面的逗號初始化器使用也是如此,其構造了一個臨時對象,是一個2X3的隨機矩陣,然後在輸出時,被求值得到結果。最重要的是mat = (MatrixXf(2,2) << 0, 1, 1, 0).finished() * mat;
,在裏面有一個反對角單位矩陣:KaTeX parse error: No such environment: smallmatrix at position 14: \bigl[ \begin{̲s̲m̲a̲l̲l̲m̲a̲t̲r̲i̲x̲}̲ 0 & 1 \\ 1 & 0…。這裏的.finish()
是必須的,表示需要對表達式對象進行求值。
這是一個2X2的單位對角矩陣乘以2X3的矩陣:
//matrix_initial4.cpp
#include <Eigen/Dense>
#include <iostream>
using namespace std;
using namespace Eigen;
int main()
{
// random matrix.
MatrixXf mat = MatrixXf::Random(2, 3);
std::cout <<" random matrix: " << endl << mat << std::endl << std::endl;
//
//mat = (MatrixXf(2,2) << 0, 1, 1, 0) * mat; // compile error: invalid operands to binary expression
mat = (MatrixXf(2,2) << 0, 1, 1, 0).finished() * mat;
std::cout << " new matrix: " << endl << mat << std::endl;
}
執行結果:
$ g++ -I /usr/local/include/eigen3 matrix_initial4.cpp -o matrix_initial4
$
$ ./matrix_initial4
random matrix:
-0.999984 0.511211 0.0655345
-0.736924 -0.0826997 -0.562082
new matrix:
-0.736924 -0.0826997 -0.562082
-0.999984 0.511211 0.0655345