[转]c++矩阵运算库Eigen

原文地址:http://www.cnblogs.com/goingupeveryday/p/5699053.html

c++矩阵运算库Eigen

  Eigen 的简介和下载安装

最近因为要写机械臂的运动学控制程序,因此难免就要在C++中进行矩阵运算。然而C++本身不支持矩阵运算,Qt库中的矩阵运算能力也相当有限,因此考虑寻求矩阵运算库Eigen的帮助。 

Eigen是一个C++线性运算的模板库:他可以用来完成矩阵,向量,数值解等相关的运算。(Eigen is a C++ template library for linear algebra: matrices, vectors, numerical solvers, and related algorithms.)

Eigen库下载: http://eigen.tuxfamily.org/index.php?title=Main_Page

Eigen库的使用相当方便,将压缩包中的Eigen文件夹拷贝到项目目录下,直接包含其中的头文件即可使用,省去了使用Cmake进行编译的烦恼。

Eigen官网有快速入门的参考文档:http://eigen.tuxfamily.org/dox/group__QuickRefPage.html

  Eigen简单上手使用

要实现相应的功能只需要包含头相应的头文件即可:

Core

#include <Eigen/Core>

Matrix and Array classes, basic linear algebra (including triangular and selfadjoint products), array manipulation
Geometry

#include <Eigen/Geometry>

TransformTranslationScalingRotation2D and 3D rotations (QuaternionAngleAxis)
LU

#include <Eigen/LU>

Inverse, determinant, LU decompositions with solver (FullPivLUPartialPivLU)
Cholesky

#include <Eigen/Cholesky>

LLT and LDLT Cholesky factorization with solver
Householder

#include <Eigen/Householder>

Householder transformations; this module is used by several linear algebra modules
SVD

#include <Eigen/SVD>

SVD decomposition with least-squares solver (JacobiSVD)
QR

#include <Eigen/QR>

QR decomposition with solver (HouseholderQRColPivHouseholderQRFullPivHouseholderQR)
Eigenvalues

#include <Eigen/Eigenvalues>

Eigenvalue, eigenvector decompositions (EigenSolverSelfAdjointEigenSolver,ComplexEigenSolver)
Sparse

#include <Eigen/Sparse>

Sparse matrix storage and related basic linear algebra (SparseMatrix, DynamicSparseMatrix,SparseVector)
 

#include <Eigen/Dense>

Includes Core, Geometry, LU, Cholesky, SVD, QR, and Eigenvalues header files
 

#include <Eigen/Eigen>

Includes Dense and Sparse header files (the whole Eigen library)

基本的矩阵运算只需要包含Dense即可

基本的数据类型:Array, matrix and vector

声明:

#include<Eigen/Dense>

...
//1D objects
Vector4d  v4;
Vector2f  v1(x, y);
Array3i   v2(x, y, z);
Vector4d  v3(x, y, z, w);
VectorXf  v5; // empty object
ArrayXf   v6(size);

//2D objects
atrix4f  m1;
MatrixXf  m5; // empty object
MatrixXf  m6(nb_rows, nb_columns);

赋值:

//
Vector3f  v1;     v1 << x, y, z;
ArrayXf   v2(4);  v2 << 1, 2, 3, 4;

//
Matrix3f  m1;   m1 << 1, 2, 3,
                      4, 5, 6,
                      7, 8, 9;

int rows=5, cols=5;
MatrixXf m(rows,cols);
m << (Matrix3f() << 1, 2, 3, 4, 5, 6, 7, 8, 9).finished(),
     MatrixXf::Zero(3,cols-3),
     MatrixXf::Zero(rows-3,3),
     MatrixXf::Identity(rows-3,cols-3);
cout << m;

//对应的输出:
1 2 3 0 0
4 5 6 0 0
7 8 9 0 0
0 0 0 1 0
0 0 0 0 1

Resize矩阵:

//
vector.resize(size);
vector.resizeLike(other_vector);
vector.conservativeResize(size);

//
matrix.resize(nb_rows, nb_cols);
matrix.resize(Eigen::NoChange, nb_cols);
matrix.resize(nb_rows, Eigen::NoChange);
matrix.resizeLike(other_matrix);
matrix.conservativeResize(nb_rows, nb_cols);

元素读取:

vector(i);
vector[i];

matrix(i,j);

矩阵的预定义:

//vector x
x.setZero();
x.setOnes();
x.setConstant(value);
x.setRandom();
x.setLinSpaced(size, low, high);

VectorXf::Unit(4,1) == Vector4f(0,1,0,0)
                    == Vector4f::UnitY()

//matrix x
x.setZero(rows, cols);
x.setOnes(rows, cols);
x.setConstant(rows, cols, value);
x.setRandom(rows, cols);

x.setIdentity();//单位矩阵
x.setIdentity(rows, cols);     

映射操作,可以将c语言类型的数组映射为矩阵或向量:

(注意:

1.映射只适用于对一维数组进行操作,如果希望将二维数组映射为对应的矩阵,可以借助"mat.row(i)=Map<Vector> v(data[i],n)"进行循环来实现,其中data为二维数组名,n为数组第一维的维度。

2.应设置之后数组名和矩阵或向量名其实指向同一个地址,只是名字和用法不同,另外,对其中的任何一个进行修改都会修改另外一个)

//连续映射
float data[] = {1,2,3,4};
Map<Vector3f> v1(data);       // uses v1 as a Vector3f object
Map<ArrayXf>  v2(data,3);     // uses v2 as a ArrayXf object
Map<Array22f> m1(data);       // uses m1 as a Array22f object
Map<MatrixXf> m2(data,2,2);   // uses m2 as a MatrixXf object

//间隔映射
float data[] = {1,2,3,4,5,6,7,8,9};
Map<VectorXf,0,InnerStride<2> >  v1(data,3);                      // = [1,3,5]
Map<VectorXf,0,InnerStride<> >   v2(data,3,InnerStride<>(3));     // = [1,4,7]
Map<MatrixXf,0,OuterStride<3> >  m2(data,2,3);                    // both lines     |1,4,7|
Map<MatrixXf,0,OuterStride<> >   m1(data,2,3,OuterStride<>(3));   // are equal to:  |2,5,8|

算术运算:

add 
subtract

mat3 = mat1 + mat2;           mat3 += mat1;

mat3 = mat1 - mat2;           mat3 -= mat1;

scalar product

mat3 = mat1 * s1;             mat3 *= s1;           mat3 = s1 * mat1;

mat3 = mat1 / s1;             mat3 /= s1;

matrix/vector 
products *

col2 = mat1 * col1;

row2 = row1 * mat1;           row1 *= mat1;

mat3 = mat1 * mat2;           mat3 *= mat1;

transposition 
adjoint *

mat1 = mat2.transpose();      mat1.transposeInPlace();

mat1 = mat2.adjoint();        mat1.adjointInPlace();

dotproduct 
inner product *

scalar = vec1.dot(vec2);

scalar = col1.adjoint() * col2;

scalar = (col1.adjoint() * col2).value();

outer product *

mat = col1 * col2.transpose();

norm
normalization*

scalar = vec1.norm();         scalar = vec1.squaredNorm()

vec2 = vec1.normalized();     vec1.normalize(); // inplace

cross product*

#include <Eigen/Geometry>

vec3 = vec1.cross(vec2);

Coefficient-wise & Array operators

Coefficient-wise operators for matrices and vectors:

Matrix API * Via Array conversions

mat1.cwiseMin(mat2)

mat1.cwiseMax(mat2)

mat1.cwiseAbs2()

mat1.cwiseAbs()

mat1.cwiseSqrt()

mat1.cwiseProduct(mat2)

mat1.cwiseQuotient(mat2)

mat1.array().min(mat2.array())

mat1.array().max(mat2.array())

mat1.array().abs2()

mat1.array().abs()

mat1.array().sqrt()

mat1.array() * mat2.array()

mat1.array() / mat2.array()

Array operators:*

Arithmetic operators

array1 * array2     array1 / array2     array1 *= array2    array1 /= array2

array1 + scalar     array1 - scalar     array1 += scalar    array1 -= scalar

Comparisons          

array1 < array2     array1 > array2     array1 < scalar     array1 > scalar

array1 <= array2    array1 >= array2    array1 <= scalar    array1 >= scalar

array1 == array2    array1 != array2    array1 == scalar    array1 != scalar

Trigo, power, and 
misc functions 
and the STL variants

array1.min(array2)

array1.max(array2)

array1.abs2()

array1.abs()                  abs(array1)

array1.sqrt()                 sqrt(array1)

array1.log()                  log(array1)

array1.exp()                  exp(array1)

array1.pow(exponent)          pow(array1,exponent)

array1.square()

array1.cube()

array1.inverse()

array1.sin()                  sin(array1)

array1.cos()                  cos(array1)

array1.tan()                  tan(array1)

array1.asin()                 asin(array1)

array1.acos()                 acos(array1)

Reductions

Eigen provides several reduction methods such as: minCoeff()maxCoeff()sum()prod()trace()*norm()*squaredNorm()*all(), and any(). All reduction operations can be done matrix-wise, column-wiseor row-wise. Usage example:

5 3 1

mat = 2 7 8

9 4 6

mat.minCoeff();

1

mat.colwise().minCoeff();

2 3 1

mat.rowwise().minCoeff();

1

2

4

Typical use cases of all() and any():

//Typical use cases of all() and any():

if((array1 > 0).all()) ...      // if all coefficients of array1 are greater than 0 ...
if((array1 < array2).any()) ... // if there exist a pair i,j such that array1(i,j) < array2(i,j) ...

Sub-matrices

Read-write access to a columnor a rowof a matrix (or array):

mat1.row(i) = mat2.col(j);

mat1.col(j1).swap(mat1.col(j2));

Read-write access to sub-vectors:

Default versions Optimized versions when the size 
is known at compile time
 

vec1.head(n)

vec1.head<n>()

the first n coeffs

vec1.tail(n)

vec1.tail<n>()

the last n coeffs

vec1.segment(pos,n)

vec1.segment<n>(pos)

the n coeffs in the 
range [pos : pos + n - 1]

Read-write access to sub-matrices:

mat1.block(i,j,rows,cols)

(more)

mat1.block<rows,cols>(i,j)

(more)

the rows x cols sub-matrix 
starting from position (i,j)

mat1.topLeftCorner(rows,cols)

mat1.topRightCorner(rows,cols)

mat1.bottomLeftCorner(rows,cols)

mat1.bottomRightCorner(rows,cols)

mat1.topLeftCorner<rows,cols>()

mat1.topRightCorner<rows,cols>()

mat1.bottomLeftCorner<rows,cols>()

mat1.bottomRightCorner<rows,cols>()

the rows x cols sub-matrix 
taken in one of the four corners

mat1.topRows(rows)

mat1.bottomRows(rows)

mat1.leftCols(cols)

mat1.rightCols(cols)

mat1.topRows<rows>()

mat1.bottomRows<rows>()

mat1.leftCols<cols>()

mat1.rightCols<cols>()

specialized versions of block() 
when the block fit two corners

top

Miscellaneous operations

Reverse

Vectors, rows, and/or columns of a matrix can be reversed (see DenseBase::reverse()DenseBase::reverseInPlace(),VectorwiseOp::reverse()).

vec.reverse()           mat.colwise().reverse()   mat.rowwise().reverse()

vec.reverseInPlace()

Replicate

Vectors, matrices, rows, and/or columns can be replicated in any direction (see DenseBase::replicate(),VectorwiseOp::replicate())

vec.replicate(times)                                          vec.replicate<Times>

mat.replicate(vertical_times, horizontal_times)               mat.replicate<VerticalTimes, HorizontalTimes>()

mat.colwise().replicate(vertical_times, horizontal_times)     mat.colwise().replicate<VerticalTimes, HorizontalTimes>()

mat.rowwise().replicate(vertical_times, horizontal_times)     mat.rowwise().replicate<VerticalTimes, HorizontalTimes>()

top

Diagonal, Triangular, and Self-adjoint matrices

(matrix world *)

Diagonal matrices

Operation Code
view a vector as a diagonal matrix

mat1 = vec1.asDiagonal();

Declare a diagonal matrix

DiagonalMatrix<Scalar,SizeAtCompileTime> diag1(size);

diag1.diagonal() = vector;

Access the diagonaland super/sub diagonalsof a matrix as a vector (read/write)

vec1 = mat1.diagonal();        mat1.diagonal() = vec1;      // main diagonal

vec1 = mat1.diagonal(+n);      mat1.diagonal(+n) = vec1;    // n-th super diagonal

vec1 = mat1.diagonal(-n);      mat1.diagonal(-n) = vec1;    // n-th sub diagonal

vec1 = mat1.diagonal<1>();     mat1.diagonal<1>() = vec1;   // first super diagonal

vec1 = mat1.diagonal<-2>();    mat1.diagonal<-2>() = vec1;  // second sub diagonal

Optimized products and inverse

mat3  = scalar * diag1 * mat1;

mat3 += scalar * mat1 * vec1.asDiagonal();

mat3 = vec1.asDiagonal().inverse() * mat1

mat3 = mat1 * diag1.inverse()

Triangular views

TriangularView gives a view on a triangular part of a dense matrix and allows to perform optimized operations on it. The opposite triangular part is never referenced and can be used to store other information.

Note
The .triangularView() template member function requires the template keyword if it is used on an object of a type that depends on a template parameter; see The template and typename keywords in C++ for details.
Operation Code
Reference to a triangular with optional 
unit or null diagonal (read/write):

m.triangularView<Xxx>()

Xxx = UpperLowerStrictlyUpperStrictlyLowerUnitUpper,UnitLower

Writing to a specific triangular part:
(only the referenced triangular part is evaluated)

m1.triangularView<Eigen::Lower>() = m2 + m3

Conversion to a dense matrix setting the opposite triangular part to zero:

m2 = m1.triangularView<Eigen::UnitUpper>()

Products:

m3 += s1 * m1.adjoint().triangularView<Eigen::UnitUpper>() * m2

m3 -= s1 * m2.conjugate() * m1.adjoint().triangularView<Eigen::Lower>()

Solving linear equations:
 
 

L1.triangularView<Eigen::UnitLower>().solveInPlace(M2)

L1.triangularView<Eigen::Lower>().adjoint().solveInPlace(M3)

U1.triangularView<Eigen::Upper>().solveInPlace<OnTheRight>(M4)

Symmetric/selfadjoint views

Just as for triangular matrix, you can reference any triangular part of a square matrix to see it as a selfadjoint matrix and perform special and optimized operations. Again the opposite triangular part is never referenced and can be used to store other information.

Note
The .selfadjointView() template member function requires the template keyword if it is used on an object of a type that depends on a template parameter; see The template and typename keywords in C++ for details.
Operation Code
Conversion to a dense matrix:

m2 = m.selfadjointView<Eigen::Lower>();

Product with another general matrix or vector:

m3  = s1 * m1.conjugate().selfadjointView<Eigen::Upper>() * m3;

m3 -= s1 * m3.adjoint() * m1.selfadjointView<Eigen::Lower>();

Rank 1 and rank K update: 
 

M1.selfadjointView<Eigen::Upper>().rankUpdate(M2,s1);

M1.selfadjointView<Eigen::Lower>().rankUpdate(M2.adjoint(),-1);

Rank 2 update: ( )

M.selfadjointView<Eigen::Upper>().rankUpdate(u,v,s);

Solving linear equations:
( )

// via a standard Cholesky factorization

m2 = m1.selfadjointView<Eigen::Upper>().llt().solve(m2);

// via a Cholesky factorization with pivoting

m2 = m1.selfadjointView<Eigen::Lower>().ldlt().solve(m2);

更多内容请关注我的博客:http://markma.tk/

时间: 2024-10-16 23:08:49

[转]c++矩阵运算库Eigen的相关文章

Duanxx的Design abroad: C++矩阵运算库Eigen 概要

一.概要 这两天想起来要做神经网络的作业了,要求用C++完毕神经网络的算法. 摆在面前的第一个问题就是,神经网络算法中大量用到了矩阵运算.可是C++不像matlab那样对矩阵运算有非常好的支持.本来准备自己写一个C++的矩阵运算的代码的,google了一下后.找到了几个不错的C++矩阵运算库,我选用的是Eigen这个C++矩阵运算库. Eigen有很丰富的功能: l  支持全部大小的矩阵运算,从非常小的大小固定的矩阵运算.到随意大的稠密矩阵的运算,甚至连稀疏矩阵的运算它也支持. l  支持当前全

Duanxx的Design abroad: C++矩阵运算库Eigen 概述

一.概述 这两天想起来要做神经网络的作业了,要求用C++完成神经网络的算法. 摆在面前的第一个问题就是,神经网络算法中大量用到了矩阵运算,但是C++不像matlab那样对矩阵运算有很好的支持,本来准备自己写一个C++的矩阵运算的代码的,google了一下后,找到了几个不错的C++矩阵运算库,我选用的是Eigen这个C++矩阵运算库. Eigen有非常丰富的功能: l  支持所有大小的矩阵运算,从很小的大小固定的矩阵运算,到任意大的稠密矩阵的运算,甚至连稀疏矩阵的运算它也支持. l  支持当前所有

【转】C++矩阵运算库推荐

[原文链接]http://www.52ml.net/13002.html Armadillo:C++下的Matlab替代品 地址:http://arma.sourceforge.net/ 许可证:MPL 2.0 目前使用比较广的C++矩阵运算库之一,是在C++下使用Matlab方式操作矩阵很好的选择,许多Matlab的矩阵操作函数都可以找到对应,这 对习惯了Matlab的人来说实在是非常方便,另外如果要将Matlab下做研究的代码改写成C++,使用Armadillo也会很方便,这里有一个简易的M

C++矩阵运算库推荐

最近在几个地方都看到有人问C++下用什么矩阵运算库比较好,顺便做了个调查,做一些相关的推荐吧.主要针对稠密矩阵,有时间会再写一个稀疏矩阵的推荐. Armadillo:C++下的Matlab替代品 地址:http://arma.sourceforge.net/ 许可证:MPL 2.0 目前使用比较广的C++矩阵运算库之一,是在C++下使用Matlab方式操作矩阵很好的选择,许多Matlab的矩阵操作函数都可以找到对应,这 对习惯了Matlab的人来说实在是非常方便,另外如果要将Matlab下做研究

C++矩阵库——Eigen

发现一个C++矩阵库Eigen,还没有深入学习,先记录下几个链接吧,以后再认真学学. Eigen主页:http://eigen.tuxfamily.org/index.php?title=Main_Page 初步体验矩阵库:http://www.cnblogs.com/tornadomeet/archive/2012/12/11/2813842.html C++矩阵处理工具——Eigen:http://blog.csdn.net/abcjennifer/article/details/77819

C++矩阵库Eigen的仿Matlab矩阵运算

与其他矩阵库相比,Eigen(Visit)相比,Eigen只需要拷贝所有include文件到指定位置,无需编译即可使用;此外,用法上模仿Matlab矩阵操作; 上述特点,使其具有很好的实用性. 附上测试代码,以便学习和使用. //http://eigen.tuxfamily.org/dox/group__QuickRefPage.html #include <iostream> #include <Eigen/Dense> using namespace std; using na

C++矩阵库 Eigen 快速入门

最近需要用 C++ 做一些数值计算,之前一直采用Matlab 混合编程的方式处理矩阵运算,非常麻烦,直到发现了 Eigen 库,简直相见恨晚,好用哭了. Eigen 是一个基于C++模板的线性代数库,直接将库下载后放在项目目录下,然后包含头文件就能使用,非常方便.此外,Eigen的接口清晰,稳定高效.唯一的问题是之前一直用 Matlab,对 Eigen 的 API 接口不太熟悉,如果能有 Eigen 和 Matlab 对应的说明想必是极好的,终于功夫不负有心人,让我找到了,原文在这里,不过排版有

线性算术的C++模板库 Eigen

Eigen 是一个线性算术的C++模板库,包括:vectors, matrices, 以及相关算法.功能强大.快速.优雅以及支持多平台. Eigen中的矩阵类型一般都是用类似MatrixXXX来表示,可以根据该名字来判断其数据类型,比如说'd'代表double并不是用来表示整数的,;'f'代表float; 'i'代表整数;'c'代表complex,即复数:'d'表示dynamic,即表示矩阵中有些维数是不确定的,动态的--举例子比如说:Matrix2cd,表示的是2*2维的,其每个元素都是复数,

《视觉slam十四讲》之第3讲-实践Eigen库

<视觉slam十四讲>之第3讲-实践Eigen库 Eigen库的安装 sudo apt-get install libeigen3-dev 注:Eigen是一个由纯头文件搭建的线性代数库,头文件安装路径为/usr/include/eigen3/. 实例1:Eigen的基础运算 #include <iostream> #include <ctime> #include <Eigen/Core> // Eigen 部分 #include <Eigen/De