Eigen : Matrix and Vector arithmetic
Eigen库 有重载关于Matrix与Vector的计算符,这样我们可以很方便的得到矩阵运算后的结果。
一些基本运算符:+,-,*,/,+=,-=,*=,/=
普通的矩阵加减法运算:
#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; }
Output:
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
乘法运算:
#include <iostream> #include <Eigen/Dense> using namespace Eigen; int main() { Matrix2d a; a << 1, 2, 3, 4; Vector3d v(1,2,3); std::cout << "a * 2.5 =\n" << a * 2.5 << std::endl; std::cout << "0.1 * v =\n" << 0.1 * v << std::endl; std::cout << "Doing v *= 2;" << std::endl; v *= 2; std::cout << "Now v =\n" << v << std::endl; }
Output:
a * 2.5 = 2.5 5 7.5 10 0.1 * v = 0.1 0.2 0.3 Doing v *= 2; Now v = 2 4 6
除此之外,Eigen库关于运算还有个很人性化的地方
比如,VectorXf a(50),b(50),c(50),d(50);
...
a = 3 * b + 4 * c + 5 * d;
会自动编译为:
for(int i = 0 ; i < 50 ; i++){
a[i] = 3*b[i] + 4*c[i] + 5*d[i];
}
注意:如果你看了上面一段关于表达式模板的内容,担心做m=m*m会引起别名问题,暂时放心。Eigen将矩阵乘法作为一种特殊情况处理,并注意在这里引入一个临时的,所以它将把m=m*m编译为:
temp = m*m;
m = temp;
然后是一些特殊的计算函数,十分便利:
sum() //矩阵内元素和 prod() //元素积 mean() //元素平均 minCoeff() //最小元素 maxCoeff() //最大元素 trace() //对角线和 transpose() //转置 conjugate() //共轭 adjoint() //共轭转置
普通计算函数示例代码:
#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; }
Output:
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
并且minCoeff()与maxCoeff()能够得到相应元素的下标,可使用如下方法实现:
int i,j;
minCoeff(&i,&j);
maxCoeff(&i,&j);
得到的i,j就是相应元素的横纵坐标。
转置,共轭,共轭转置示例代码:
MatrixXcf a = MatrixXcf::Random(2,2); //随机2x2矩阵 cout << "Here is the matrix a\n" << a << endl; cout << "Here is the matrix a^T\n" << a.transpose() << endl; cout << "Here is the conjugate of a\n" << a.conjugate() << endl; cout << "Here is the matrix a^*\n" << a.adjoint() << endl;
Output:
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)
注意:至于基本的算术运算符,transpose()和 adjoint()只是返回一个代理对象,而不进行实际的转置。如果你做b = a.transpose(),那么在将结果写入b的同时就会对transpose进行评估。如果执行a = a.transpose(),那么在转置的评估完成之前,Eigen就开始将结果写入a中。因此,指令a = a.transpose()并不像人们所期望的那样,用它的转置替换a。
还有两个函数差点忘记说了,分别是dot()与cross(),一个是计算点积,一个是计算叉积,非常实用的两个函数!
补充两个编译时容易出现的错误:(官方文档详细说明)
Eigen checks the validity of the operations that you perform. When possible, it checks them at compile time, producing compilation errors. These error messages can be long and ugly, but Eigen writes the important message in UPPERCASE_LETTERS_SO_IT_STANDS_OUT. For example:(Eigen会检查你所执行的操作的有效性,在可能的情况下,它会在编译时检查它们,产生编译错误。在可能的情况下,它在编译时检查它们,产生编译错误。这些错误信息可能又长又丑,但Eigen会把重要的信息用UPPERCASE_LETTERS_SO_IT_STANDS_OUT写出来,如下:)
解释:第一个就是两种不同类型的矩阵相乘会出现SIZE报错,这是理所当然的,第二个就是检查动态大小时,不能在编译时进行检查!
-------------------------------------------------------------------------------------------------------------
有些内容暂时用不到,以后补充。