概述
密集矩阵和数组操作
矩阵类
为了阅读方便大多翻译自下面官方文档。
参考:
http://eigen.tuxfamily.org/dox/group__TutorialMatrixClass.html
在Eigen 中,所有矩阵和向量都是Matrix模板类的对象。向量只是矩阵的一种特殊情况,向量是 1 行或 1 列的矩阵。
Matrix的前三个模板参数
Matrix事实上包括六个参数,我们只需要掌握前三个就可。
前三个参数分别是:
Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>
Scalar
是标量类型,即系数的类型。也就是说,如果您想要一个浮点矩阵,请选择float
。有关所有支持的标量类型的列表以及如何扩展对新类型的支持,请参阅标量类型。
RowsAtCompileTime
和ColsAtCompileTime
是编译时已知的矩阵的行数和列数。
我们提供了很多方便的 类型定义。例如,Matrix4f
是一个 4x4 的浮点矩阵。
typedef Matrix<float, 4, 4> Matrix4f;
我们在下面讨论这些方便的类型定义。
向量
向量是特殊 的矩阵。
例如:typedef Matrix<float, 3, 1> Vector3f; 为一个浮点型列向量,
typedef Matrix<int, 1, 2> RowVector2i; 为一个整形行向量。
特殊值 Dynamic
Eigen不限于其维度在编译时已知的矩阵。在RowsAtCompileTime
和ColsAtCompileTime
模板参数可以采取特殊值Dynamic
,这表明大小在编译时是未知的,所以必须作为运行时变量来处理。在Eigen术语中,这样的大小被称为动态 大小;而在编译时已知的大小称为固定 大小。例如 typedefMatrixXd
表示具有动态大小的双精度矩阵,定义如下:
typedef Matrix<double, Dynamic, Dynamic> MatrixXd;
同样,我们定义了一个不言自明的 typedefVectorXi
如下:
typedef Matrix<int, Dynamic, 1> VectorXi;
例如,固定数量行和动态列,如下所示:
Matrix<float, 3, Dynamic>
构造
默认构造始终可用,从不执行任何动态内存分配,也从不初始化矩阵系数。
Matrix3f a;
MatrixXf b;
a
是一个 3×3 矩阵,带有未初始化系数的普通 float[9] 数组,
b
是一个动态大小的矩阵,其大小当前为 0×0,并且其系数数组尚未分配。
系数存取器
Eigen中的主要系数访问器和修改器是重载的括号运算符。对于矩阵,始终首先传递行索引。对于向量,只需传递一个索引。编号从 0 开始。这个例子是不言自明的:
例如:
#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
int main()
{
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;
VectorXd v(2);
v(0) = 4;
v(1) = v(0) - 1;
std::cout << "Here is the vector v:n" << v << std::endl;
}
输出:
Here is the matrix m:
3 -1
2.5 1.5
Here is the vector v:
4
3
矩阵和向量系数可以使用所谓的逗号初始化语法方便地设置
Matrix3f m;
m << 1, 2, 3,
4, 5, 6,
7, 8, 9;
std::cout << m
;
输出:
1 2 3
4 5 6
7 8 9
调整大小
可以通过rows()、cols()和size()检索矩阵的当前大小。这些方法分别返回行数、列数和系数数。调整动态大小矩阵的大小是通过resize()方法完成的。
#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
int main()
{
MatrixXd m(2,5);
m.resize(4,3);
std::cout << "The matrix m is of size "
<< m.rows() << "x" << m.cols() << std::endl;
std::cout << "It has " << m.size() << " coefficients" << std::endl;
VectorXd v(2);
v.resize(5);
std::cout << "The vector v is of size " << v.size() << std::endl;
std::cout << "As a matrix, v is of size "
<< v.rows() << "x" << v.cols() << std::endl;
矩阵和向量算数
加减
当然,左侧和右侧必须具有相同的行数和列数。它们还必须具有相同的Scalar
类型,因为Eigen不进行自动类型提升。这里的操作员是:
- 二元运算符 + 如
a+b
- 二元运算符 - 如
a-b
- 一元运算符 - 如
-a
- 复合运算符 += 如
a+=b
- 复合运算符 -= 如
a-=b
#include <iostream> #include <Eigen/Dense> using namespace Eigen; int main() { Matrix2d a; a << 1, 2, 3, 4; MatrixXd b(2,2); b << 2, 3, 1, 4; std::cout << "a + b =n" << a + b << std::endl; std::cout << "a - b =n" << a - b << std::endl; std::cout << "Doing a += b;" << std::endl; a += b; std::cout << "Now a =n" << a << std::endl; Vector3d v(1,2,3); Vector3d w(1,0,0); std::cout << "-v + w - v =n" << -v + w - v << std::endl; }
a + b =
3 5
4 8
a - b =
-1 -1
2 0
Doing a += b;
Now a =
3 5
4 8
-v + w - v =
-1
-4
-6
转置共轭伴随
The transpose aT, conjugate a¯, and adjoint (i.e., conjugate transpose) a∗ of a matrix or vector a are obtained by the member functions transpose(), conjugate(), and adjoint(), respectively.
记住转置共轭和伴随矩阵的函数即可。
MatrixXcf a = MatrixXcf::Random(2,2);
cout << "Here is the matrix an" << a << endl;
cout << "Here is the matrix a^Tn" << a.transpose() << endl;
cout << "Here is the conjugate of an" << a.conjugate() << endl;
cout << "Here is the matrix a^*n" << a.adjoint() << endl;
目录
矩阵类
Matrix的前三个模板参数
构造
系数存取器
调整大小
矩阵和向量算数
加减
转置共轭伴随
矩阵跟矩阵以及矩阵跟向量乘法
基本算数归约运算
数组类及操作
获取数组内部值
数组的加减乘除以及矩阵数组转换
Here is the matrix a
(-1,-0.737) (0.0655,-0.562)
(0.511,-0.0827) (-0.906,0.358)
Here is the matrix a^T
(-1,-0.737) (0.511,-0.0827)
(0.0655,-0.562) (-0.906,0.358)
Here is the conjugate of a
(-1,0.737) (0.0655,0.562)
(0.511,0.0827) (-0.906,-0.358)
Here is the matrix a^*
(-1,0.737) (0.511,0.0827)
(0.0655,0.562) (-0.906,-0.358
矩阵跟矩阵以及矩阵跟向量乘法
这部分很简单,无脑操作即可
#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
int main()
{
Matrix2d mat;
mat << 1, 2,
3, 4;
Vector2d u(-1,1), v(2,0);
std::cout << "Here is mat*mat:n" << mat*mat << std::endl;
std::cout << "Here is mat*u:n" << mat*u << std::endl;
std::cout << "Here is u^T*mat:n" << u.transpose()*mat << std::endl;
std::cout << "Here is u^T*v:n" << u.transpose()*v << std::endl;
std::cout << "Here is u*v^T:n" << u*v.transpose() << std::endl;
std::cout << "Let's multiply mat by itself" << std::endl;
mat = mat*mat;
std::cout << "Now mat is mat:n" << mat << std::endl;
基本算数归约运算
Eigen还提供了一些归约操作来将给定的矩阵或向量归约到单个值,例如总和(由sum()计算)、乘积(prod())或最大值(maxCoeff())和最小值(minCoeff() ) 的所有系数。
#include <iostream>
#include <Eigen/Dense>
using namespace std;
int main()
{
Eigen::Matrix2d mat;
mat << 1, 2,
3, 4;
cout << "Here is mat.sum(): " << mat.sum() << endl;
cout << "Here is mat.prod(): " << mat.prod() << endl;
cout << "Here is mat.mean(): " << mat.mean() << endl;
cout << "Here is mat.minCoeff(): " << mat.minCoeff() << endl;
cout << "Here is mat.maxCoeff(): " << mat.maxCoeff() << endl;
cout << "Here is mat.trace(): " << mat.trace() << endl;
}
结果:
Here is mat.sum(): 10
Here is mat.prod(): 24
Here is mat.mean(): 2.5
Here is mat.minCoeff(): 1
Here is mat.maxCoeff(): 4
Here is mat.trace(): 5
数组类及操作
Array是一个类模板,它采用与Matrix相同的模板参数。与Matrix 一样,前三个模板参数是必需的:
Array<typename Scalar, int Ro
wsAtCompileTime, int ColsAtCompileTime>
无法复制加载中的内容
获取数组内部值
跟矩阵一样
#include <Eigen/Dense>
#include <iostream>
using namespace Eigen;
using namespace std;
int main()
{
ArrayXXf m(2,2);
// assign some values coefficient by coefficient
m(0,0) = 1.0; m(0,1) = 2.0;
m(1,0) = 3.0; m(1,1) = m(0,1) + m(1,0);
// print values to standard output
cout << m << endl << endl;
// using the comma-initializer is also allowed
m << 1.0,2.0,
3.0,4.0;
// print values to standard output
cout << m << endl;
}
数组的加减乘除以及矩阵数组转换
两个数组的加减与矩阵相同。如果两个数组具有相同的大小,并且加法或减法是按系数进行的,则该操作是有效的。数组还支持array + scalar
将标量添加到数组中的每个系数的形式的表达式。这提供了不能直接用于Matrix对象的功能。
首先,当然您可以将数组乘以标量,这与矩阵的工作方式相同。数组与矩阵根本不同的地方在于,当您将两个相乘时。矩阵将乘法解释为矩阵乘积,数组将乘法解释为系数乘积。因此,两个数组可以相乘当且仅当它们具有相同的维度。
#include <Eigen/Dense>
#include <iostream>
using namespace Eigen;
using namespace std;
int main()
{
ArrayXXf a(3,3);
ArrayXXf b(3,3);
a << 1,2,3,
4,5,6,
7,8,9;
b << 1,2,3,
1,2,3,
1,2,3;
// Adding two arrays
cout << "a + b = " << endl << a + b << endl << endl;
// Subtracting a scalar from an array
cout << "a - 2 = " << endl << a - 2 << endl
#include <Eigen/Dense>
#include <iostream>
using namespace Eigen;
using namespace std;
int main()
{
ArrayXXf a(2,2);
ArrayXXf b(2,2);
a << 1,2,
3,4;
b << 5,6,
7,8;
cout << "a * b = " << endl << a * b << endl;
}
矩阵表达式有一个.array()方法,可以将它们“转换”为数组表达式,因此可以轻松应用系数运算。相反,数组表达式有一个.matrix()方法。与所有Eigen表达式抽象一样,这没有任何运行时成本(前提是您让编译器优化)。既.array()和.matrix()可被用作右值和作为左值。
Eigen禁止在表达式中混合矩阵和数组。例如,您不能直接添加矩阵和数组;运算+
符的操作数要么都是矩阵,要么都是数组。但是,使用.array()和.matrix()很容易从一种转换到另一种。这条规则的例外是赋值运算符:允许将矩阵表达式赋值给数组变量,或将数组表达式赋值给矩阵变量。
#include <Eigen/Dense>
#include <iostream>
using namespace Eigen;
using namespace std;
int main()
{
MatrixXf m(2,2);
MatrixXf n(2,2);
MatrixXf result(2,2);
m << 1,2,
3,4;
n << 5,6,
7,8;
result = m * n;
cout << "-- Matrix m*n: --" << endl << result << endl << endl;
result = m.array() * n.array();
cout << "-- Array m*n: --" << endl << result << endl << endl;
result = m.cwiseProduct(n);
cout << "-- With cwiseProduct: --" << endl << result << endl << endl;
result = m.array() + 4;
cout << "-- Array m + 4: --" << endl << result << endl << endl;
}
结果:
-- Matrix m*n: --
19 22
43 50
-- Array m*n: --
5 12
21 32
-- With cwiseProduct: --
5 12
21 32
-- Array m + 4: --
5 6
7 8
最后
以上就是长情皮皮虾为你收集整理的Eigen关于矩阵的介绍矩阵类矩阵和向量算数数组类及操作的全部内容,希望文章能够帮你解决Eigen关于矩阵的介绍矩阵类矩阵和向量算数数组类及操作所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复