Eigen學習筆記19:Quick reference guide

模塊和頭文件

Eigen分爲一個核心模塊和幾個其他模塊。每個模塊都有一個相應的頭文件,必須包含該頭文件才能使用該模塊。The Dense and Eigen header files are provided to conveniently gain access to several modules at once.

模塊 頭文件 內容
Core

#include <Eigen/Core>

MatrixArray 類,基本的線性代數計算(including triangular and selfadjoint products),array 處理
Geometry

#include <Eigen/Geometry>

變換,平移,縮放,2D旋轉,3D旋轉(QuaternionAngleAxis)
LU

#include <Eigen/LU>

逆,行列式,LU 分解及求解器 (FullPivLUPartialPivLU)
Cholesky

#include <Eigen/Cholesky>

LLT and LDLT Cholesky分解及求解器
Householder

#include <Eigen/Householder>

Householder transformations;該模塊被多個線性代數計算庫使用
SVD

#include <Eigen/SVD>

SVD 分解及 最小二乘求解器 (JacobiSVDBDCSVD)
QR

#include <Eigen/QR>

QR 分解及其求解器with solver (HouseholderQRColPivHouseholderQRFullPivHouseholderQR)
Eigenvalues

#include <Eigen/Eigenvalues>

特徵值, 特徵向量分解(EigenSolverSelfAdjointEigenSolverComplexEigenSolver)
Sparse

#include <Eigen/Sparse>

稀疏矩陣存儲及其相關的線性代數計算(SparseMatrixSparseVector)
(see Quick reference guide for sparse matrices for details on sparse modules)
 

#include <Eigen/Dense>

包含了 Core, Geometry, LU, Cholesky, SVD, QR, and Eigenvalues 頭文件
 

#include <Eigen/Eigen>

包含了Dense and Sparse 頭文件 (整個 Eigen 庫)

Array, matrix and vector 類型

Eigen提供了兩種Dense對象:均由模板類Matrix表示的數學矩陣和向量,and general 1D and 2D arrays represented by the template class Array:

typedef Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime, Options> MyMatrixType;
typedef Array<Scalar, RowsAtCompileTime, ColsAtCompileTime, Options> MyArrayType;
  • Scalar is the scalar type of the coefficients (例如:floatdoubleboolint等等).
  • RowsAtCompileTimeColsAtCompileTime是Matrix的行數和列數。
  • Options可以是ColMajorRowMajor,默認值爲ColMajor。(有關更多選項,請參見Matrix類)

允許所有組合:you can have a matrix with a fixed number of rows and a dynamic number of columns等等。

以下都是有效的:

Matrix<double, 6, Dynamic>                  // Dynamic number of columns (heap allocation)
Matrix<double, Dynamic, 2>                  // Dynamic number of rows (heap allocation)
Matrix<double, Dynamic, Dynamic, RowMajor>  // Fully dynamic, row major (heap allocation)
Matrix<double, 13, 3>                       // Fully fixed (usually allocated on stack)

在大多數情況下, you can simply use one of the convenience typedefs for matrices and arrays. 一些例子:

矩陣 數組
Matrix <float,Dynamic,Dynamic> <=> MatrixXf
Matrix <double,Dynamic,1> <=> VectorXd
Matrix <int,1,Dynamic> <=> RowVectorXi
Matrix <float,3,3> <=> Matrix3f
Matrix <float,4,1> <=> Vector4f
Array <float,Dynamic,Dynamic> <=> ArrayXXf
Array <double,Dynamic,1> <=> ArrayXd
Array <int,1,Dynamic> <=> RowArrayXi
Array <float,3,3> <=> Array33f
Array <float,4,1> <=> Array4f

the matrix and array 的轉換:

Array44f a1, a1;
Matrix4f m1, m2;
m1 = a1 * a2;                  // coeffwise product, implicit conversion from array to matrix.
a1 = m1 * m2;                  // matrix product, implicit conversion from matrix to array.
a2 = a1 + m1.array();          // mixing array and matrix is forbidden
m2 = a1.matrix() + m1;         // and explicit conversion is required.
ArrayWrapper<Matrix4f> m1a(m1);// m1a is an alias for m1.array(), they share the same coefficients
MatrixWrapper<Array44f> a1m(a1);
In the rest of this document we will use the following symbols to emphasize the features which are specifics to a given kind of object:
  • linear algebra matrix and vector only
  • array objects only

基本矩陣運算

  1D objects 2D objects Notes
構造函數

Vector4d v4;

Vector2f v1(x, y);

Array3i v2(x, y, z);

Vector4d v3(x, y, z, w);

VectorXf v5;   // empty object

ArrayXf v6(size);

Matrix4f m1;

MatrixXf m5;      // empty object

MatrixXf m6(nb_rows, nb_columns);

By default, the coefficients
are left uninitialized
逗號初始化

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;

output:

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

 

運行時確定信息

vector.size();

vector.innerStride();

vector.data();

matrix.rows();              matrix.cols();

matrix.innerSize();     matrix.outerSize();

matrix.innerStride(); matrix.outerStride();

matrix.data();

Inner/Outer* are storage order dependent
編譯時的信息

ObjectType::Scalar ObjectType::RowsAtCompileTime

ObjectType::RealScalar ObjectType::ColsAtCompileTime

ObjectType::Index ObjectType::SizeAtCompileTime

 
重新分配大小

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);

no-op if the new sizes match,
otherwise data are lost

resizing with data preservation

 

獲取元素

(範圍檢查)

vector(i) vector.x()

vector[i] vector.y()

vector.z()

vector.w()

matrix(i,j)

Range checking is disabled if
NDEBUG or EIGEN_NO_DEBUG is defined

 

獲取元素

(沒有範圍檢查)

vector.coeff(i)

vector.coeffRef(i)

matrix.coeff(i,j)

matrix.coeffRef(i,j)

 

 

賦值/複製

object = expression;

object_of_float = expression_of_double.cast<float>();

the destination is automatically resized (if possible)

 

預定以矩陣

固定大小的矩陣或向量 動態大小的矩陣 動態大小的 vector

typedef {Matrix3f|Array33f} FixedXD;

FixedXD x;

x = FixedXD::Zero();

x = FixedXD::Ones();

x = FixedXD::Constant(value);

x = FixedXD::Random();

x = FixedXD::LinSpaced(size, low, high);

x.setZero();

x.setOnes();

x.setConstant(value);

x.setRandom();

x.setLinSpaced(size, low, high);

typedef {MatrixXf|ArrayXXf} Dynamic2D;

Dynamic2D x;

x = Dynamic2D::Zero(rows, cols);

x = Dynamic2D::Ones(rows, cols);

x = Dynamic2D::Constant(rows, cols, value);

x = Dynamic2D::Random(rows, cols);

N/A

x.setZero(rows, cols);

x.setOnes(rows, cols);

x.setConstant(rows, cols, value);

x.setRandom(rows, cols);

N/A

typedef {VectorXf|ArrayXf} Dynamic1D;

Dynamic1D x;

x = Dynamic1D::Zero(size);

x = Dynamic1D::Ones(size);

x = Dynamic1D::Constant(size, value);

x = Dynamic1D::Random(size);

x = Dynamic1D::LinSpaced(size, low, high);

x.setZero(size);

x.setOnes(size);

x.setConstant(size, value);

x.setRandom(size);

x.setLinSpaced(size, low, high);

 

單位矩陣

x = FixedXD::Identity();

x.setIdentity();

Vector3f::UnitX() // 1 0 0

Vector3f::UnitY() // 0 1 0

Vector3f::UnitZ() // 0 0 1

x = Dynamic2D::Identity(rows, cols);

x.setIdentity(rows, cols);

N/A

N/A

VectorXf::Unit(size,i)

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

== Vector4f::UnitY()

Mapping external arrays

Contiguous
memory

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

Typical usage
of strides

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();

dot product
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);

元素和數組運算符

除上述運算符外,Eigen supports numerous coefficient-wise operator and functions. 它們中的大多數在array-world *中明確地有意義。以下運算符很容易用於數組,或者可通過.array()用於向量和矩陣:

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

array1.min(array2) array1.max(array2) array1.min(scalar) array1.max(scalar)

Trigo, power, and
misc functions
and the STL-like variants

array1.abs2()

array1.abs() abs(array1)

array1.sqrt() sqrt(array1)

array1.log() log(array1)

array1.log10() log10(array1)

array1.exp() exp(array1)

array1.pow(array2) pow(array1,array2)

array1.pow(scalar) pow(array1,scalar)

pow(scalar,array2)

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)

array1.atan() atan(array1)

array1.sinh() sinh(array1)

array1.cosh() cosh(array1)

array1.tanh() tanh(array1)

array1.arg() arg(array1)

array1.floor() floor(array1)

array1.ceil() ceil(array1)

array1.round() round(aray1)

array1.isFinite() isfinite(array1)

array1.isInf() isinf(array1)

array1.isNaN() isnan(array1)

以下係數運算符可用於所有類型的表達式(矩陣,向量和數組),以及實數或複數標量類型:

Eigen's API STL-like APIs* Comments

mat1.real()

mat1.imag()

mat1.conjugate()

real(array1)

imag(array1)

conj(array1)

// read-write, no-op for real expressions

// read-only for real, read-write for complexes

// no-op for real expressions

Some coefficient-wise operators 可用於 matrices and vectors 通過 cwise* methods:

Matrix API * Via Array conversions

mat1.cwiseMin(mat2) mat1.cwiseMin(scalar)

mat1.cwiseMax(mat2) mat1.cwiseMax(scalar)

mat1.cwiseAbs2()

mat1.cwiseAbs()

mat1.cwiseSqrt()

mat1.cwiseInverse()

mat1.cwiseProduct(mat2)

mat1.cwiseQuotient(mat2)

mat1.cwiseEqual(mat2) mat1.cwiseEqual(scalar)

mat1.cwiseNotEqual(mat2)

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

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

mat1.array().abs2()

mat1.array().abs()

mat1.array().sqrt()

mat1.array().inverse()

mat1.array() * mat2.array()

mat1.array() / mat2.array()

mat1.array() == mat2.array() mat1.array() == scalar

mat1.array() != mat2.array()

兩種API之間的主要區別在於: the one based on cwise* methods returns an expression in the matrix world, while the second one (based on .array()) returns an array expression. 回想一下.array() 計算代價是沒有成本的,它僅更改可用的API和數據解釋。

It is also very simple to apply any user defined function foo using DenseBase::unaryExpr together with std::ptr_fun (c++03), std::ref (c++11), or lambdas (c++11):

mat1.unaryExpr(std::ptr_fun(foo));
mat1.unaryExpr(std::ref(foo));
mat1.unaryExpr([](double x) { return foo(x); });

Reductions

Eigen 提供了reduction methods 如: minCoeff() maxCoeff() sum() prod() trace() *norm() *squaredNorm() *all() , and any() .All reduction operations can be done matrix-wise, column-wise or row-wise .

用法:

             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

Special versions of minCoeff and maxCoeff :

int i, j;
s = vector.minCoeff(&i);        // s == vector[i]
s = matrix.maxCoeff(&i, &j);    // s == matrix(i,j)

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) ...

子矩陣

Read-write access to a column or a row of 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

其他操作

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()

複製

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>()

對角, 三角化, and Self-adjoint 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 diagonal and super/sub diagonals of 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 給出了密集矩陣的三角形部分的視圖,並允許對其執行優化的操作。The opposite triangular part is never referenced and can be used to store other information.

注意: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; 有關詳細信息,請參見C ++中的template和typename關鍵字

Operation Code
Reference to a triangular with optional
unit or null diagonal (read/write):

m.triangularView<Xxx>()


Xxx = UpperLowerStrictlyUpperStrictlyLowerUnitUpperUnitLower
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>()

   

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, 可以引用方矩陣的任何三角形部分以將其視爲自伴矩陣並執行特殊的優化操作。 Again the opposite triangular part is never referenced and can be used to store other information.

注意: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; 有關詳細信息,請參見C ++中的template和typename關鍵字

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>();

   

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

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

 

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

 

// 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);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章