C++矩阵库 Eigen 快速入门 最近需要用 C++ 做一些数值计算,之前一直采用Matlab 混合编程的方式处理矩阵运算,非常麻烦,直到发现了 Eigen 库,简直相见恨晚,好用哭了。 Eigen 是一个基于C++模板的线性代数库,直接将库下载后放在项目目录下,然后包含头文件就能使用,非常方便。此外,Eigen的接口清晰,稳定高效。唯一的问题是之前一直用 Matlab,对 Eigen 的 API 接口不太熟悉,如果能有 Eigen 和 Matlab 对应的说明想必是极好的,终于功夫不负有心人,让我找到了,原文在这里,不过排版有些混乱,我将其重新整理了一下,方便日后查询。
Eigen 矩阵定义
文章图片
#includeMatrix A; // Fixed rows and cols. Same as Matrix3d. Matrix B; // Fixed rows, dynamic cols. Matrix C; // Full dynamic. Same as MatrixXd. Matrix E; // Row major; default is column-major. Matrix3f P, Q, R; // 3x3 float matrix. Vector3f x, y, z; // 3x1 float matrix. RowVector3f a, b, c; // 1x3 float matrix. VectorXd v; // Dynamic column vector of doubles // Eigen// Matlab// comments x.size()// length(x)// vector size C.rows()// size(C,1)// number of rows C.cols()// size(C,2)// number of columns x(i)// x(i+1)// Matlab is 1-based C(i,j)// C(i+1,j+1)//
文章图片
Eigen 基础使用
文章图片
// Basic usage // Eigen// Matlab// comments x.size()// length(x)// vector size C.rows()// size(C,1)// number of rows C.cols()// size(C,2)// number of columns x(i)// x(i+1)// Matlab is 1-based C(i, j)// C(i+1,j+1)//A.resize(4, 4); // Runtime error if assertions are on. B.resize(4, 9); // Runtime error if assertions are on. A.resize(3, 3); // Ok; size didn't change. B.resize(3, 9); // Ok; only dynamic cols changed.A << 1, 2, 3,// Initialize A. The elements can also be 4, 5, 6,// matrices, which are stacked along cols 7, 8, 9; // and then the rows are stacked. B << A, A, A; // B is three horizontally stacked A's. A.fill(10); // Fill A with all 10's.
文章图片
Eigen 特殊矩阵生成
文章图片
// Eigen// Matlab MatrixXd::Identity(rows,cols)// eye(rows,cols) C.setIdentity(rows,cols)// C = eye(rows,cols) MatrixXd::Zero(rows,cols)// zeros(rows,cols) C.setZero(rows,cols)// C = ones(rows,cols) MatrixXd::Ones(rows,cols)// ones(rows,cols) C.setOnes(rows,cols)// C = ones(rows,cols) MatrixXd::Random(rows,cols)// rand(rows,cols)*2-1// MatrixXd::Random returns uniform random numbers in (-1, 1). C.setRandom(rows,cols)// C = rand(rows,cols)*2-1 VectorXd::LinSpaced(size,low,high)// linspace(low,high,size)' v.setLinSpaced(size,low,high)// v = linspace(low,high,size)'
文章图片
Eigen 矩阵分块
文章图片
// Matrix slicing and blocks. All expressions listed here are read/write. // Templated size versions are faster. Note that Matlab is 1-based (a size N // vector is x(1)...x(N)). // Eigen// Matlab x.head(n)// x(1:n) x.head()// x(1:n) x.tail(n)// x(end - n + 1: end) x.tail ()// x(end - n + 1: end) x.segment(i, n)// x(i+1 : i+n) x.segment (i)// x(i+1 : i+n) P.block(i, j, rows, cols)// P(i+1 : i+rows, j+1 : j+cols) P.block (i, j)// P(i+1 : i+rows, j+1 : j+cols) P.row(i)// P(i+1, :) P.col(j)// P(:, j+1) P.leftCols ()// P(:, 1:cols) P.leftCols(cols)// P(:, 1:cols) P.middleCols (j)// P(:, j+1:j+cols) P.middleCols(j, cols)// P(:, j+1:j+cols) P.rightCols ()// P(:, end-cols+1:end) P.rightCols(cols)// P(:, end-cols+1:end) P.topRows ()// P(1:rows, :) P.topRows(rows)// P(1:rows, :) P.middleRows (i)// P(i+1:i+rows, :) P.middleRows(i, rows)// P(i+1:i+rows, :) P.bottomRows ()// P(end-rows+1:end, :) P.bottomRows(rows)// P(end-rows+1:end, :) P.topLeftCorner(rows, cols)// P(1:rows, 1:cols) P.topRightCorner(rows, cols)// P(1:rows, end-cols+1:end) P.bottomLeftCorner(rows, cols)// P(end-rows+1:end, 1:cols) P.bottomRightCorner(rows, cols)// P(end-rows+1:end, end-cols+1:end) P.topLeftCorner ()// P(1:rows, 1:cols) P.topRightCorner ()// P(1:rows, end-cols+1:end) P.bottomLeftCorner ()// P(end-rows+1:end, 1:cols) P.bottomRightCorner ()// P(end-rows+1:end, end-cols+1:end)
文章图片
Eigen 矩阵元素交换
// Of particular note is Eigen's swap function which is highly optimized. // Eigen// Matlab R.row(i) = P.col(j); // R(i, :) = P(:, i) R.col(j1).swap(mat1.col(j2)); // R(:, [j1 j2]) = R(:, [j2, j1])
Eigen 矩阵转置
文章图片
// Views, transpose, etc; all read-write except for .adjoint(). // Eigen// Matlab R.adjoint()// R' R.transpose()// R.' or conj(R') R.diagonal()// diag(R) x.asDiagonal()// diag(x) R.transpose().colwise().reverse(); // rot90(R) R.conjugate()// conj(R)
文章图片
Eigen 矩阵乘积
文章图片
// All the same as Matlab, but matlab doesn't have *= style operators. // Matrix-vector.Matrix-matrix.Matrix-scalar. y= M*x; R= P*Q; R= P*s; a= b*M; R= P - Q; R= s*P; a *= M; R= P + Q; R= P/s; R *= Q; R= s*P; R += Q; R *= s; R -= Q; R /= s;
文章图片
Eigen 矩阵单个元素操作
文章图片
// Vectorized operations on each element independently // Eigen// Matlab R = P.cwiseProduct(Q); // R = P .* Q R = P.array() * s.array(); // R = P .* s R = P.cwiseQuotient(Q); // R = P ./ Q R = P.array() / Q.array(); // R = P ./ Q R = P.array() + s.array(); // R = P + s R = P.array() - s.array(); // R = P - s R.array() += s; // R = R + s R.array() -= s; // R = R - s R.array() < Q.array(); // R < Q R.array() <= Q.array(); // R <= Q R.cwiseInverse(); // 1 ./ P R.array().inverse(); // 1 ./ P R.array().sin()// sin(P) R.array().cos()// cos(P) R.array().pow(s)// P .^ s R.array().square()// P .^ 2 R.array().cube()// P .^ 3 R.cwiseSqrt()// sqrt(P) R.array().sqrt()// sqrt(P) R.array().exp()// exp(P) R.array().log()// log(P) R.cwiseMax(P)// max(R, P) R.array().max(P.array())// max(R, P) R.cwiseMin(P)// min(R, P) R.array().min(P.array())// min(R, P) R.cwiseAbs()// abs(P) R.array().abs()// abs(P) R.cwiseAbs2()// abs(P.^2) R.array().abs2()// abs(P.^2) (R.array() < s).select(P,Q); // (R < s ? P : Q)
文章图片
Eigen 矩阵化简
文章图片
// Reductions. int r, c; // Eigen// Matlab R.minCoeff()// min(R(:)) R.maxCoeff()// max(R(:)) s = R.minCoeff(&r, &c)// [s, i] = min(R(:)); [r, c] = ind2sub(size(R), i); s = R.maxCoeff(&r, &c)// [s, i] = max(R(:)); [r, c] = ind2sub(size(R), i); R.sum()// sum(R(:)) R.colwise().sum()// sum(R) R.rowwise().sum()// sum(R, 2) or sum(R')' R.prod()// prod(R(:)) R.colwise().prod()// prod(R) R.rowwise().prod()// prod(R, 2) or prod(R')' R.trace()// trace(R) R.all()// all(R(:)) R.colwise().all()// all(R) R.rowwise().all()// all(R, 2) R.any()// any(R(:)) R.colwise().any()// any(R) R.rowwise().any()// any(R, 2)
文章图片
Eigen 矩阵点乘
// Dot products, norms, etc. // Eigen// Matlab x.norm()// norm(x).Note that norm(R) doesn't work in Eigen. x.squaredNorm()// dot(x, x)Note the equivalence is not true for complex x.dot(y)// dot(x, y) x.cross(y)// cross(x, y) Requires #include
Eigen 矩阵类型转换
文章图片
//// Type conversion // Eigen// Matlab A.cast(); // double(A) A.cast (); // single(A) A.cast (); // int32(A) A.real(); // real(A) A.imag(); // imag(A) // if the original type equals destination type, no work is done
文章图片
Eigen 求解线性方程组 Ax = b
文章图片
// Solve Ax = b. Result stored in x. Matlab: x = A \ b. x = A.ldlt().solve(b)); // A sym. p.s.d.#includex = A.llt() .solve(b)); // A sym. p.d.#include x = A.lu().solve(b)); // Stable and fast. #include x = A.qr().solve(b)); // No pivoting.#include x = A.svd() .solve(b)); // Stable, slowest. #include // .ldlt() -> .matrixL() and .matrixD() // .llt()-> .matrixL() // .lu()-> .matrixL() and .matrixU() // .qr()-> .matrixQ() and .matrixR() // .svd()-> .matrixU(), .singularValues(), and .matrixV()
文章图片
Eigen 矩阵特征值
文章图片
// Eigenvalue problems // Eigen// Matlab A.eigenvalues(); // eig(A); EigenSolvereig(A); // [vec val] = eig(A) eig.eigenvalues(); // diag(val) eig.eigenvectors(); // vec // For self-adjoint matrices use SelfAdjointEigenSolver<>
文章图片
参考文献 【1】http://eigen.tuxfamily.org/dox/AsciiQuickReference.txt
【C++矩阵库 Eigen 快速入门】 【2】http://blog.csdn.net/augusdi/article/details/12907341
推荐阅读
- 个人日记|K8s中Pod生命周期和重启策略
- 学习分享|【C语言函数基础】
- C++|C++浇水装置问题
- 数据结构|C++技巧(用class类实现链表)
- C++|从零开始学C++之基本知识
- 步履拾级杂记|VS2019的各种使用问题及解决方法
- leetcode题解|leetcode#106. 从中序与后序遍历序列构造二叉树
- 动态规划|暴力递归经典问题
- 麦克算法|4指针与队列
- 遇见蓝桥遇见你|小唐开始刷蓝桥(一)2020年第十一届C/C++ B组第二场蓝桥杯省赛真题