C++ eigen_c++第三方库

C++ eigen_c++第三方库前言Eigen就是一个线性代数的C++库。它对矩阵(MatrixMatrix)和向量(VectorVector)等相关线性代数的运算操作进行了比较系统的实现。一、矩阵1.定义矩阵模板函数共包含六个参数template<typename_Scalar,int_Rows,int_Cols,int_Options,int_MaxRows,int_MaxC…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

一、前言

        Eigen就是一个线性代数的C++库。它对矩阵(MatrixMatrix)和向量(VectorVector)等相关线性代数的运算操作进行了比较系统的实现。

二、Eigen库的矩阵

        1. 定义

        矩阵模板函数共包含六个参数

template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
  • typename _Scalar:矩阵元素的类型;
  • int _Rows:矩阵的行数;
  • int _Cols:矩阵的列数;
  •  int _Options:矩阵是行主序(RowMajor)或列主序(ColMajor),默认是列主序;
  • int _MaxRows:矩阵的最大行数;
  • int _MaxCols:矩阵的最大列数;

        举例:

Eigen::Matrix<int, 3, 4> mat1;              //  3x4 的 int 类型的矩阵 mat1
Eigen::Matrix<double, 3, Dynamic> mat2;     //  3x? 的 double 类型的矩阵 mat2
Eigen::Matrix<float, Dynamic, 4> mat3;      //  ?x4 的 float 类型的矩阵 mat3
Eigen::Matrix<long, Dynamic, Dynamic> mat4; //  ?x? 的 long 类型的矩阵 mat4

        动态矩阵:在 Eigen 中可以用 Dynamic 表示行或者列数未知,所以在定义一个矩阵时并不能确定矩阵的大小,只有在运行时才可以确定大小,然后进行动态分配。

        静态矩阵:在定义时便明确给定了行数以及列数,在编译时就可以分配好内存。

        2. 类型

        在 EigenEigen 中 typedef 了很多矩阵的类型,通常命名为 Matrix前缀加一个长度为 1∼4 的字符串 S 的命名——MatrixS。

        其中 S 可以用来判断该矩阵类型,数字 n 表示 n ∗ n,n 的范围是2∼4,字母 d、f、i、cd、f、i、c 表示 double、float、int、complexdouble、float、int、complex,另外 X 表示行或者列数未知的矩阵。

举例:

typedef Matrix<std::complex<double>, 2, 2> Eigen::Matrix2cd;            //  2x2 的 cd 类型的矩阵
typedef Matrix<double, 2, 2> Eigen::Matrix2d;                           //  2x2 的 d 类型的矩阵
typedef Matrix<std::complex<double>, 2, Dynamic> Eigen::Matrix2Xcd;     //  2x? 的 cd 类型的矩阵
typedef Matrix<std::complex<float>, Dynamic, 2> Eigen::MatrixX2cf;      //  ?x2 的 cf 类型的矩阵
typedef Matrix<std::complex<double>, Dynamic, Dynamic> Eigen::MatrixXcd;//  ?x? 的 cd 类型的矩阵
typedef Matrix<int, Dynamic, Dynamic> Eigen::MatrixXi;                  //  ?x? 的 i 类型的矩阵

        3. 赋值与访问

        (1)Eigen::Matrix 使用 ()访问赋值数据,矩阵之间通过 = 来进行赋值(拷贝)。

        举例:

x = mat(a, b);  //  获取到矩阵 mat 的 a 行 b 列的元素并赋值给 x
mat(b, a) = x;  //  将 x 赋值给矩阵 mat 的 b 行 a 列
mat1 = mat2;    //  将矩阵 mat2 赋值(拷贝)给矩阵 mat1

        注意:

        通过 = 进行矩阵之间的拷贝时,如果左右两侧矩阵尺寸不一样并且左侧矩阵为动态矩阵,那么会将左侧矩阵的尺寸修改为与右侧一致。

        (2)在 Eigen 中重载了 << 可以用来赋值矩阵,也可以用来 cout 输出矩阵。

MatrixXf m(4, 4);   //  定义一个 4x4 的 float 类型的动态矩阵
m << 1, 2, 3, 4,
     5, 6, 7, 8,
     9, 10, 11, 12,
     13, 14, 15, 16;//  赋值
std::cout << m;     //  输出 m

        (3)Eigen 矩阵可以进行分块操作,通过成员函数 block() 获取某一部分矩阵。

mat = mat1.block(i, j, p, q);   //  从矩阵 mat1 的 i 行 j 列开始获取一个 p 行 q 列的子矩阵
mat = mat1.block<p, q>(i, j);   //  从矩阵 mat1 的 i 行 j 列开始获取一个 p 行 q 列的子矩阵(动态矩阵)

        (4)Eigen 矩阵可以使用成员函数 row()、col() 来获取某一行或者某一列。

mat = mat1.row(i);  //  获取 mat1 的第 i 行
mat = mat1.col(j);  //  获取 mat1 的第 j 列  

        (5)Eigen 提供了从边角开始提取子矩阵的方法。

描述 动态矩阵 静态矩阵
左上角 pxq mat.topLeftCorner(p,q) mat.topLeftCorner<p,q>()
左下角 pxq mat.bottomLeftCorner(p,q) mat.bottomLeftCorner<p,q>()
右上角 pxq mat.topRightCorner(p,q) mat.topRightCorner<p,q>()
右下角 pxq mat.bottomRightCorner(p,q) mat.bottomRightCorner<p,q>()
前 p 行 mat.topRows(p) mat.topRows<p>()
后 p 行 mat.bottomRows(p) mat.bottomRows<p>()
前 q 列 mat.leftCols(q) mat.leftCols<q>()
后 q 列 mat.rightCols(q) mat.rightCols<q>()

        (6)Eigen 矩阵还可以使用成员函数 fill() 进行统一赋值。

mat.fill(n);    //  将 mat 的所有元素均赋值为 n

        4. 运算

        (1)Eigen 重载了 +、−(减)、∗、/、−(负)、+=、−=、∗=、/=+、−(减)、∗、/、−(负)、+=、−=、∗=、/=。

        举例:

mat = mat1 + mat2;  //  +
mat = mat1 - mat2;  //  -(减)
mat = mat1 * mat2;  //  *
mat = mat1 * n;     //  *
mat = mat1 / n;     //  /
mat = -mat1;        //  -(负)
mat += mat1;        //  +=
mat -= mat1;        //  -=
mat *= mat1;        //  *=
mat *= n;           //  *=
mat /= n;           //  /=

        (2)对于 MatrixMatrix 的转置矩阵、共轭矩阵、伴随矩阵、对角矩阵可以通过成员函数 transpose()、conjugate()、adjoint()、diagonal()来获得。如果想要在原矩阵上进行转换,则需要通过成员函数 transposeInPlace()、conjugateInPlace()、adjointInPlace()。

        举例:

mat = mat1.transpose(); //  获取 mat1 的转置矩阵
mat = mat1.conjugate(); //  获取 mat1 的共轭矩阵
mat = mat1.adjoint();   //  获取 mat1 的伴随矩阵
mat = mat1.diagonal();  //  获取 mat1 的对角矩阵
mat1.transposeInPlace();//  mat1 转换为对应的转置矩阵
mat1.conjugateInPlace();//  mat1 转换为对应的共轭矩阵
mat1.adjointInPlace();  //  mat1 转换为对应的伴随矩阵
mat1.diagonalInPlace(); //  mat1 转换为对应的对角矩阵
mat1.transpose().colwise().reverse();   //  mat1 Rot90

        (3)特殊矩阵

mat = MatrixXd::Identity(rows, cols);   //  生成 rows x cols 的单位阵
mat.setIdentity(rows, cols);            //  将 mat 设置为 rows x cols 的单位阵
mat = MatrixXd::Zero(rows, cols);       //  生成 rows x cols 的零矩阵
mat.setZero(rows, cols);                //  将 mat 设置为 rows x cols 的零矩阵
mat = MatrixXd::Ones(rows, cols);       //  生成 rows x cols 的壹矩阵
mat.setOnes(rows, cols);                //  将 mat 设置为 rows x cols 的壹矩阵
mat = MatrixXd::Random(rows, cols);     //  生成 rows x cols 的随机矩阵
mat.setRandom(rows, cols);              //  将 mat 设置为 rows x cols 的随机矩阵

        (4)其它

        当前矩阵的行数、列数、大小可以通过成员函数 rows()、cols()、size()来获取。

rows = mat.rows();  //  获取行数
cols = mat.cols();  //  获取列数
size = mat.size();  //  获取大小

        动态矩阵可以通过成员函数 resize() 来进行修改大小,静态矩阵是不可以 resize() 的,并且动态矩阵 resize() 后元素不能保证不变。

mat.resize(rows, cols); //  将动态矩阵 mat 大小尺寸修改为 rows x cols

三、Eigen库的向量

        1. 类型与存储

        类似于矩阵的类型,不过前缀从 Matrix 改成 Vector。

        举例:

typedef Matrix<std::complex<float>, 2, 1> Eigen::Vector2cf; //  cf 类型的 2 向量
typedef Matrix<int, 2, 1> Eigen::Vector2i;                  //  i 类型的 2 向量
typedef Matrix<double, 4, 1> Eigen::Vector4d;               //  d 类型的 4 向量
typedef Matrix<float, Dynamic, 1> Eigen::VectorXf;          //  f 类型的 ? 向量

        上述的 Vector 默认的都是列向量,如果是行向量,在命名上则需要加上 Row 前缀。

        举例:

typedef Matrix<float, 1, 2> Eigen::RowVector2f;                 //  f 类型的 2 向量(行向量)
typedef Matrix<std::complex<double>, 1, 4> Eigen::RowVector4cd; //  cd 类型的 4 向量(行向量)

        动态向量:不指定向量的尺寸,只有在运行时才会分配对应的内存;

        静态向量:一开始就定义好了大小,在编译时分配好内存。

        2. 访问与赋值

        (1)类似于 Matrix 的操作,不过向量也可以使用 [],另外向量对前四个元素的访问与赋值还可以通过成员函数 x()、y()、z()、w()来操作。

        举例:

x = vec(n);     //  获取向量 vec 的第 n 个元素并赋值给 x
x = vec[n];
x = vec.x();    //  获取向量 vec 的第一个元素并赋值给 x
y = vec.y();    //  获取向量 vec 的第二个元素并赋值给 y
z = vec.z();    //  获取向量 vec 的第三个元素并赋值给 z
w = vec.w();    //  获取向量 vec 的第四个元素并赋值给 w
vec(n) = x;     //  将 x 赋值给 vec 的第 n 个元素

        (2)Eigen 向量也提供了一些分块操作来获取子向量。

描述 静态向量 动态向量
前 n 个元素 vec.head(n) vec.head<n>()
后 n 个元素 vec.tail(n) vec.tail<n>()
从 i 开始取 n 个元素 vec.segment(i,n) vec.segment<n>(i)

        3. 运算

        (1)Eigen 向量提供了 norm()、squareNorm()、dot()、cross()等成员函数。

        举例:

x.norm()        //  norm(x)     Note that norm(R) doesn't work in Eigen.
x.squaredNorm()
x.dot(y)        //  dot(x, y)
x.cross(y)      //  cross(x, y) Requires #include <Eigen/Geometry>

        (2)获取尺寸

size = vec.size();  //  获取 vec 的尺寸

参考文章

C++矩阵库 Eigen 快速入门
Eigen教程1-基础

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/180221.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号