06 进阶初始化

进阶初始化

[TOC]

逗号初始化

输入数据

​ 可以直接用逗号表达式输入数据。

Matrix3f m;
m << 1, 2, 3,
4, 5, 6,
7, 8, 9;
std::cout << m;
/*
1 2 3
4 5 6
7 8 9
*/

输入矩阵

​ 也可以将矩阵作为数据进行输入。

输入向量

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

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

RowVectorXd joined(7);
joined << vec1, vec2;
std::cout << "joined = " << joined << std::endl;

输入块矩阵

MatrixXf matA(2, 2);
matA << 1, 2, 3, 4;
MatrixXf matB(4, 4);
matB << matA, matA/10, matA/10, matA;
std::cout << matB << std::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
*/

输入行或列(row/col)

Matrix3f m;
m.row(0) << 1, 2, 3;
m.block(1,0,2,2) << 4, 5, 7, 8;
m.col(2).tail(2) << 6, 9;
std::cout << m;
/*
1 2 3
4 5 6
7 8 9
*/

特殊的矩阵和Array

  • Zero()

  • Constant(value)

  • Random()

  • Identity()

  • LinSpaced(size, low, high):仅用于向量或者一行/列,输入指定数目间隔的一组数

Zero

std::cout << "A fixed-size array:\n";
Array33f a1 = Array33f::Zero();
std::cout << a1 << "\n\n";


std::cout << "A one-dimensional dynamic-size array:\n";
ArrayXf a2 = ArrayXf::Zero(3);
std::cout << a2 << "\n\n";


std::cout << "A two-dimensional dynamic-size array:\n";
ArrayXXf a3 = ArrayXXf::Zero(3, 4);
std::cout << a3 << "\n";

/*
A fixed-size array:
0 0 0
0 0 0
0 0 0

A one-dimensional dynamic-size array:
0
0
0

A two-dimensional dynamic-size array:
0 0 0 0
0 0 0 0
0 0 0 0
*/

LinSpaced

ArrayXXf table(10, 4);
table.col(0) = ArrayXf::LinSpaced(10, 0, 90);
table.col(1) = M_PI / 180 * table.col(0);
table.col(2) = table.col(1).sin();
table.col(3) = table.col(1).cos();
std::cout << " Degrees Radians Sine Cosine\n";
std::cout << table << std::endl;

/*
Degrees Radians Sine Cosine
0 0 0 1
10 0.175 0.174 0.985
20 0.349 0.342 0.94
30 0.524 0.5 0.866
40 0.698 0.643 0.766
50 0.873 0.766 0.643
60 1.05 0.866 0.5
70 1.22 0.94 0.342
80 1.4 0.985 0.174
90 1.57 1 -4.37e-08
*/

Xx和SetXx

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);
std::cout << mat1 << std::endl << std::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();
std::cout << mat2 << std::endl << std::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);
std::cout << mat3 << std::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
*/

临时对象(temp obj)

​ 上述的Identity、Zero等静态函数成员看似是返回了一个矩阵,实则是返回的是一个表达式对象,这些对象在需要时计算结果为矩阵或数组,因此不存在任何开销。

​ 它们也可以用作临时对象来参与计算:

#include <iostream>
#include <Eigen/Dense>

using Eigen::MatrixXd;
using Eigen::VectorXd;

int main()
{
MatrixXd m = MatrixXd::Random(3,3);
m = (m + MatrixXd::Constant(3,3,1.2)) * 50;
std::cout << "m =" << std::endl << m << std::endl;
VectorXd v(3);
v << 1, 2, 3;
std::cout << "m * v =" << std::endl << m * v << std::endl;
}

逗号初始化的对象也可以作为临时对象参与计算:

MatrixXf mat = MatrixXf::Random(2, 3);
std::cout << mat << std::endl << std::endl;

mat = (MatrixXf(2,2) << 0, 1, 1, 0).finished() * mat; // comma-initializer

std::cout << mat << std::endl;

​ 此处的finished是必须的,来使得表达式生成对应的矩阵对象。