Eigen教程(6)

整理下Eigen库的教程,参考:http://eigen.tuxfamily.org/dox/index.html

高级初始化方法

本篇介绍几种高级的矩阵初始化方法,重点介绍逗号初始化和特殊矩阵(单位阵、零阵)。

逗号初始化

Eigen提供了逗号操作符允许我们方便地为矩阵/向量/数组中的元素赋值。顺序是从左上到右下:自左到右,从上至下。对象的尺寸需要事先指定,初始化的参数也应该和要操作的元素数目一致。

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

初始化列表不仅可以是数值也可以是vectors或matrix。

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;

输出

vec1 = 1 2 3
vec2 =  1  4  9 16
joined =  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;
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

同时逗号初始化方式也可以用来为块表达式赋值。

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

特殊的矩阵和向量

零阵:类的静态成员函数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

类似地,还有常量矩阵:Constant([rows],[cols],value),Random()随机矩阵。

单位阵Identity()方法只能使用与Matrix不使用Array,因为单位阵是个线性代数概念。

LinSpaced(size, low, high)可以从low到high等间距的size长度的序列,适用于vector和一维数组。

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

功能函数

Eigen也提供可同样功能的函数:setZero(), MatrixBase::setIdentity()和 DenseBase::setLinSpaced()。

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

三种赋值(初始化)的方式逗号初始化、特殊阵的静态方法和功能函数setXxx()。

表达式变量

上面的静态方法如 Zero()、Constant()并不是直接返回一个矩阵或数组,实际上它们返回的是是‘expression object’,只是临时被使用/被用于优化。

m = (m + MatrixXd::Constant(3,3,1.2)) * 50;

MatrixXf::Constant(3,3,1.2)构建的是一个3*3的矩阵表达式(临时变量)。

逗号初始化的方式也可以构建这种临时变量,这是为了获取真正的矩阵需要调用finished()函数:

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

输出

  0.68  0.566  0.823
-0.211  0.597 -0.605

-0.211  0.597 -0.605
  0.68  0.566  0.823

转载于:https://www.cnblogs.com/houkai/p/6351358.html

学习Eigen库的使用是C++开发者在进行科学计算、计算机视觉、机器人、机器学习等领域开发时的一项重要技能。Eigen是一个高效的C++模板库,专门用于线性代数、矩阵和向量运算,支持各种数值计算操作。 ### 一、Eigen库的基本使用 Eigen库的安装相对简单,主要依赖于CMake进行构建。用户可以从官网下载源码,使用CMake进行配置并编译安装。对于大多数Linux系统,Eigen可以通过包管理器安装,也可以手动编译安装[^3]。 Eigen库不需要编译,只需要将头文件包含到项目中即可使用。因此,使用Eigen的第一步是在项目中正确配置其包含路径。 ### 二、编写第一个Eigen程序 以下是一个简单的程序示例,演示如何使用Eigen进行矩阵运算: ```cpp #include <iostream> #include <Eigen/Dense> using Eigen::MatrixXd; int main() { // 创建一个2x2的矩阵 MatrixXd m(2, 2); m(0, 0) = 3; m(1, 0) = 2.5; m(0, 1) = -1; m(1, 1) = m(1, 0) + m(0, 1); std::cout << "Here is the matrix m:\n" << m << std::endl; // 矩阵相乘 MatrixXd product = m * m; std::cout << "Here is m*m:\n" << product << std::endl; return 0; } ``` 在该程序中,我们定义了一个2x2的矩阵,并进行了赋值和矩阵乘法操作。Eigen的语法简洁,易于使用。 ### 三、使用CMake集成Eigen 在CMake项目中集成Eigen,需要在`CMakeLists.txt`文件中添加Eigen的包含路径。例如: ```cmake include_directories(/usr/local/include/eigen3) ``` 如果使用的是Linux系统,通常Eigen会被安装到`/usr/include/eigen3`或`/usr/local/include/eigen3`目录下。确保路径正确后,编译器将能够找到Eigen的头文件并正确编译项目[^4]。 ### 四、进阶使用与注意事项 Eigen支持多种数据类型,包括固定大小和动态大小的矩阵与向量。它还支持多种运算,如矩阵分解、特征值计算、奇异值分解(SVD)等。在使用Eigen时,需要注意以下几点: - Eigen矩阵和向量默认是列优先(Column-major)存储的。 - 在多线程环境中使用Eigen时,需确保线程安全。 - Eigen的表达式模板机制可能导致编译时间较长,但运行效率高。 - 在CUDA内核中使用Eigen时,需要特别注意内存管理和编译选项。 ### 五、参考资料与学习资源 - [Eigen官方文档](https://eigen.tuxfamily.org/dox/) 提供了详尽的API参考和使用指南。 - [C++模板编程与Eigen](https://blog.youkuaiyun.com/m0_63111108/article/details/124758977?spm=1001.2014.3001.5502) 教程可以帮助理解模板编程在Eigen中的应用。 - [Eigen中文文档](https://eigen.tuxfamily.org/dox/notes/) 提供了关于预处理指令、断言、多线程等高级特性的介绍。 Eigen的学习曲线较为平缓,适合初学者入门线性代数在C++中的实现。随着对Eigen库的深入使用,开发者可以探索其更高级的功能,如自定义表达式、模板元编程等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值