Eigen⼊门之密集矩阵5-再谈Matrix初始化
简介
这⾥将讨论⼀下⾼级些的矩阵初始化⽅法。
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;identity matrix是什么意思
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.block(1,0,2,2)<<4,5,7,8;
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);
cout <<"  Degrees  Radians      Sine    Cosine\n";
cout << table << endl;
//
cout <<"-------------------------------"<< endl;
// 快捷⽅法
const int size =6;
MatrixXd mat1(size, size);
cout << mat1 << endl << endl;
// 辅助⽅法
MatrixXd mat2(size, size);
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

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。