ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Eigen库学习 ---- 5.高级初始化操作

2021-04-25 10:32:12  阅读:242  来源: 互联网

标签:初始化 Eigen 矩阵 ---- 数组 table col size


Eigen库学习 ---- 5.高级初始化操作

上篇为:Eigen库学习 ---- 4.块操作
本篇为这个链接的学习笔记。

  介绍初始化矩阵的几种高级方法,介绍如何得到单位矩阵和零矩阵等特殊矩阵。

一、逗号初始化

  Eigen提供了逗号初始化的方法,可以很容易的设置矩阵、向量或者数组的元素值。按照从左到右从上到下的顺序列出所有的元素。对象的大小需要事先指定,如果列出的元素个数太多或者太少,Eigen会报错。
例如:

	Matrix3f m;
	m << 1, 2, 3,
		4, 5, 6,
		7, 8, 9;
cout << m;

输出结果如下;

1 2 3
4 5 6
7 8 9

  此外,初始化列表的元素本身可以是向量或者矩阵。常用的方法是将向量或者矩阵连接在一起。必须要设置大小,然后才能用逗号初始值设定。
例如:

RowVectorXd vec1(3);
vec1 << 1,2,3;
cout << "vec1=" << vec1 << endl;

RowVectorXd vec2(4);
vec2 << 1,4,9,16;
cout << "vec2=" << vec2 << endl;

RowVectorXd vec3(7);
vec3 << vec1, vec2;
cout << "vec3=" << vec3 << endl;

输出结果如下:

vec1=1 2 3
vec2= 1  4  9 16
vec3= 1  2  3  1  4  9 16

  可以用相同的方法用矩阵块初始化矩阵,例如:

MatrixXf matA(2, 2);
matA << 1,2,3,4;
MatrixXf matB(4, 4);
matB << matA, matA / 10, matA / 10, matA;
cout << matB << endl;

输出结果如下:

  1   2 0.1 0.2
  3   4 0.3 0.4
0.1 0.2   1   2
0.3 0.4   3   4

  逗号初始值设定项也可用于填充块表达式,如m.row(i)。下面是一个更复杂的方法来获得与上面第一个示例相同的结果:

Matrix3f m;
	//第0行输入1,2,3
	m.row(0) << 1, 2, 3;
	//从1行0列的元素开始选择2x2的矩阵块,输入4,5,7,8
	m.block(1, 0, 2, 2) << 4, 5, 7, 8;
	//第2列的最后两个元素输入6,9
	m.col(2).tail(2) << 6, 9;
cout << m;

输出结果如下:

1 2 3
4 5 6
7 8 9

二、特殊矩阵和数组

  矩阵和数组类有静态方法,如Zero(),可用于将所有系数初始化为零。有三种变体。分别需要0个、1个、2个参数。
  第一个变体不带参数,只能用于固定大小的对象。如果要将动态大小对象初始化为零,则需要指定大小。
  第二个变体量需要一个参数,可以用于一维动态大小对象。
  第三个变体需要两个参数,可以用于二维对象。
以下示例中说明了所有三种变体:

cout << "固定大小的数组:\n";
	Array33f a1 = Array33f::Zero();
	cout << a1 << "\n\n";
	cout << "一维动态数组:\n";
	ArrayXf a2 = ArrayXf::Zero(3);
	cout << a2 << "\n\n";
	cout << "二维动态数组:\n";
	ArrayXXf a3 = ArrayXXf::Zero(3, 4);
cout << a3 << "\n";

输出结果如下:

固定大小的数组:
0 0 0
0 0 0
0 0 0

一维动态数组:
0
0
0

二维动态数组:
0 0 0 0
0 0 0 0
0 0 0 0

  类似地,Constant(value)将所有系数设置为value。如果需要指定对象的大小,那么其他参数将放在value参数之前,如matrixXd::Constant(rows,cols,value)中所示。
  方法Random()用随机系数填充矩阵或数组。
  方法identity()可以得到单位矩阵;这种方法只适用于矩阵,不适用于数组,因为“单位矩阵”是一个线性代数概念。
  方法LinSpaced(size,low,high)方法仅适用于向量和一维数组;它产生一个指定大小的向量,其系数在low和high之间等距(size)分布。
  下面的示例演示了LinSpaced()方法,它打印一个表,其中以度表示角度,以弧度表示相应的角度,以及它们的正弦和余弦。

ArrayXXf table(10, 4);
	table.col(0) = ArrayXf::LinSpaced(10, 0, 90);
	table.col(1) = 3.1415926 / 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;

输出结果如下:

  Degrees   Radians      Sine    Cosine
           0            0            0            1
          10     0.174533     0.173648     0.984808
          20     0.349066      0.34202     0.939693
          30     0.523599          0.5     0.866025
          40     0.698132     0.642788     0.766044
          50     0.872665     0.766044     0.642788
          60       1.0472     0.866025          0.5
          70      1.22173     0.939693      0.34202
          80      1.39626     0.984808     0.173648
          90       1.5708            1 -4.37114e-08

  这个例子展示了LinSpaced()返回的对象可以分配给变量(和表达式)。Eigen定义了诸如setZero()、MatrixBase::setIdentity()和DenseBase::setLinSpaced()之类的实用函数来方便地实现这一点。下面的示例对比了构造矩阵J的三种方法:

J = [ 1 0 0 1 ] J=\begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix}\quad J=[10​01​]

1.使用静态方法和赋值
2.使用setXxx()方法。
3.使用静态方法和逗号初始值设定项

const int size = 6;
	//第一种方法,使用静态方法赋值
	MatrixXd mat1(size,size);
	//左上角的3x3的矩阵块被赋值为零矩阵
	mat1.topLeftCorner(size / 2, size / 2) = MatrixXd::Zero(size / 2, size / 2);
	//右上角的3x3矩阵被赋值为单位矩阵
	mat1.topRightCorner(size / 2, size / 2) = MatrixXd::Identity(size/ 2,size/ 2);
	//左下角的3x3矩阵被赋值为单位矩阵
	mat1.bottomLeftCorner(size / 2, size / 2) = MatrixXd::Identity(size / 2, size / 2);
	//右下角的3x3矩阵被赋值为零矩阵
	mat1.bottomRightCorner(size / 2, size / 2) = MatrixXd::Zero(size / 2, size / 2);
	cout << mat1 << endl << endl;

	//第二种方法,setXxx()方法
	MatrixXd mat2(size, size);
	//左上角的3x3的矩阵块被赋值为零矩阵
	mat2.topLeftCorner(size / 2, size / 2).setZero();
	//右上角的3x3矩阵被赋值为单位矩阵
	mat2.topRightCorner(size / 2, size / 2).setIdentity();
	//左下角的3x3矩阵被赋值为单位矩阵
	mat2.bottomLeftCorner(size / 2, size / 2).setIdentity();
	//右下角的3x3矩阵被赋值为零矩阵
	mat2.bottomRightCorner(size / 2, size / 2).setZero();
	cout << mat2 << endl << endl;

	//第三种方法,使用静态方法和逗号初始化
	MatrixXd mat3(size, size);
	//左上角的3x3的矩阵块被赋值为零矩阵
	//右上角的3x3矩阵被赋值为单位矩阵
	//左下角的3x3矩阵被赋值为单位矩阵
	//右下角的3x3矩阵被赋值为零矩阵
	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 << endl;

输出结果如下:

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

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

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

三、临时对象

  矩阵可以作为临时变量使用,且不会产生任何开销。例如:

MatrixXd m(3, 3);
	m << 1, 2, 3, 4, 5, 6, 7, 8, 9;
	m = (m + MatrixXd::Constant(3, 3, 1.2) * 50);
	cout << "m=" << endl << m  << endl;
	VectorXd v(3);
	v << 1,2,3;
cout << "m*v" << endl << m * v << endl;

输出结果如下:

m=
61 62 63
64 65 66
67 68 69
m*v
374
392
410

逗号表达式也可以作为临时模板进行输入。例如:

MatrixXf mat = MatrixXf::Random(2, 3);
cout << mat << endl << endl;
mat = (MatrixXf(2, 2) << 0, 1, 1, 0).finished() * mat;
cout << mat << endl;

输出结果如下:

-0.997497  -0.613392   0.170019
  0.127171   0.617481 -0.0402539

  0.127171   0.617481 -0.0402539
 -0.997497  -0.613392   0.170019

这里需要.finished()方法,以便在临时子矩阵的逗号初始化完成后获取实际的矩阵对象。

标签:初始化,Eigen,矩阵,----,数组,table,col,size
来源: https://blog.csdn.net/qq_39400324/article/details/116117391

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有