Eigen入门之密集矩阵 2-- Matrix及Vector的计算方法
簡介
Eigen內的Matrix和Vector提供了類似C++的運算符,如+,-,*;也提供了編程的函數方法,如點乘和叉乘的dot(), cross(),如此等等。
在Eigen的Matrix類,代表矩陣matrics和向量vector,重載的運算符僅用于支持線性代數的運算,而不支持標量計算。比如matrix1 * matrix2,表示矩陣matrix 乘以 matrix2,而matrix1 + 10則不允許。
加法和減法
如大家所知,如果2個矩陣運行運算,對2個矩陣的行數和列數是有條件要求的。另外,在Eigen內,用于計算時,矩陣的系數類型必須統一,并不會內部進行類型轉換。
二元運算符 + : ma + mb;
二元運算符 - : ma - mb;
一元運算符 - : - ma;
組合運算符 +=: ma+=mb;
組合運算符 -=: ma-=mb;
示例:
// matrix_cal1.cpp #include <iostream> #include <Eigen/Dense>using namespace Eigen;int main() {Matrix2d a;a << 1, 2,3, 4;MatrixXd b(2,2);b << 5, 6,7, 8;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;std::cout << endl;Vector3d v(1,2,3);Vector3d w(1,0,0);std::cout << "-v + w - v =\n" << -v + w - v << std::endl; }執行后輸出:
$ ./matrix_cal1 a + b =6 8 10 12 a - b = -4 -4 -4 -4 Doing a += b; Now a =6 8 10 12 -v + w - v = -1 -4 -6與標量的乘、除
與標量的乘法和除法計算是支持的,重載的操作符如下:
二元運算符 * : matrix * scalar;
二元運算符 * : scalar * matrix;
二元運算符 / : matrix / scalar;
組合運算符 *=: matrix *= scalar;
組合運算符 /=: matrix /= scalar;
示例:
// matrix_cal2.cpp #include <iostream> #include <Eigen/Dense>using namespace Eigen;int main() {Matrix2d a;a << 1, 2,3, 4;std::cout << "a * 2.5 =\n" << a * 2.5 << std::endl;Vector3d v(1,2,3);std::cout << "calculating v *= 2;" << std::endl;v *= 2;std::cout << "2.0 * v =\n" << 2.0 * v << std::endl;std::cout << "Now v =\n" << v << std::endl;}執行結果:
$ ./matrix_cal2 a * 2.5 = 2.5 5 7.5 10 calculating v *= 2; 2.0 * v =48 12 Now v = 2 4 6轉置和共軛
在線性代數中,矩陣有轉置操作,共軛計算,共軛轉置計算: aTa^TaT, aˉ\bar aaˉ, a?a^*a?, Matrix提供了對應的函數:transpose(), conjugate(), and adjoint()。
說明一下: 共軛是針對復數而言的,共軛矩陣也是復數矩陣的對應的共軛矩陣。
示例程序:
// matrix_cal3.cpp #include <iostream> #include <Eigen/Dense>using namespace Eigen; using namespace std;int main() {MatrixXcf a = MatrixXcf::Random(2,2);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; }執行:
$ g++ matrix_cal3.cpp -o matrix_cal3 -I /usr/local/include/eigen3 $ ./matrix_cal3 Here is the matrix a (-0.999984,-0.736924) (0.0655345,-0.562082) (0.511211,-0.0826997) (-0.905911,0.357729) Here is the matrix a^T (-0.999984,-0.736924) (0.511211,-0.0826997) (0.0655345,-0.562082) (-0.905911,0.357729) Here is the conjugate of a(-0.999984,0.736924) (0.0655345,0.562082)(0.511211,0.0826997) (-0.905911,-0.357729) Here is the matrix a^*(-0.999984,0.736924) (0.511211,0.0826997)(0.0655345,0.562082) (-0.905911,-0.357729)對實數矩陣,并沒有對應的共軛矩陣,其共軛轉置矩陣就是其轉置矩陣。
matrix-matrix與matrix-vector的乘法
矩陣的matrix-matrix乘法,及矩陣*矩陣,是由操作符operator *完成的。而在Eigen內,向量vector也是一種特殊的矩陣,所以,matrix-vector和vector-vector的乘法也是由operator *來完成。
這里有2種運算:
- 二元運算符 * : a * b;
- 復合運算符 *=: a *= b;
示例:
// matrix_cal4.cpp #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; }執行
$ g++ matrix_cal4.cpp -o matrix_cal4 -I /usr/local/include/eigen3 $ $ ./matrix_cal4 Here is mat*mat:7 10 15 22 Here is mat*u: 1 1 Here is u^T*mat: 2 2 Here is u^T*v: -2 Here is u*v^T: -2 -02 0 Let's multiply mat by itself Now mat is mat:7 10 15 22aliasing issues與運算模板
矩陣的點乘與叉乘
使用matrix類的dot(), cross()函數,來執行矩陣的點乘和叉乘。
點乘的結果可以看出是1X1的矩陣,u * v 還可以使用u.adjoint()*v進行計算.
示例:
#include <iostream> #include <Eigen/Dense>using namespace Eigen; using namespace std;int main() {Vector3d v(1,2,3);Vector3d w(0,1,2);cout << "Dot product: " << v.dot(w) << endl;double dp = v.adjoint() * w; // automatic conversion of the inner product to a scalarcout << "Dot product via a matrix product: " << dp << endl;cout << "Cross product:\n" << v.cross(w) << endl; }執行輸出:
Dot product: 8 Dot product via a matrix product: 8 Cross product: 1 -2 1基礎算數操作–arithmetic reduction
對矩陣matrix或向量vector,提供了一些算數分解操作,比如獲取矩陣的系數之和,最大值,最小值,平均值、及對角線的相關算數。
- sum() : 系數之和
- prod() : 系數乘積
- maxCoeff() : 最大系數
- minCoeff() : 最小系數
- trace() : 對角線系數和。
注意這些函數的重載,還可以同時獲取該系數的位置。
// matrix_cal5.cpp #include <iostream> #include <Eigen/Dense>using namespace Eigen; using namespace std;int main() {Matrix3f m = Matrix3f::Random();std::ptrdiff_t i, j;float minOfM = m.minCoeff(&i,&j);cout << "Here is the matrix m:\n" << m << endl;cout << "Its minimum coefficient (" << minOfM << ") is at position (" << i << "," << j << ")\n\n";RowVector4i v = RowVector4i::Random();int maxOfV = v.maxCoeff(&i);cout << "Here is the vector v: " << v << endl;cout << "Its maximum coefficient (" << maxOfV << ") is at position " << i << endl;}執行結果如下:
$ g++ matrix_cal5.cpp -o matrix_cal5 -I /usr/local/include/eigen3 $ ./matrix_cal5 Here is the matrix m:-0.999984 -0.0826997 -0.905911-0.736924 0.0655345 0.3577290.511211 -0.562082 0.358593 Its minimum coefficient (-0.999984) is at position (0,0)Here is the vector v: 933495885 -250177384 41696341 710742668 Its maximum coefficient (933495885) is at position 0總結
以上是生活随笔為你收集整理的Eigen入门之密集矩阵 2-- Matrix及Vector的计算方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小米平板6系列最新爆料:120/144H
- 下一篇: 美国将微信、淘宝、拼多多再度列入“恶名市