1. 程式人生 > >【Eigen】Eigen介紹及簡單使用

【Eigen】Eigen介紹及簡單使用

Eigen是可以用來進行線性代數、矩陣、向量操作等運算的C++庫,它裡面包含了很多演算法。它的License是MPL2。它支援多平臺。

         Eigen採用原始碼的方式提供給使用者使用,在使用時只需要包含Eigen的標頭檔案即可進行使用。之所以採用這種方式,是因為Eigen採用模板方式實現,由於模板函式不支援分離編譯,所以只能提供原始碼而不是動態庫的方式供使用者使用。

         矩陣的定義:Eigen中關於矩陣類的模板函式中,共有六個模板引數,常用的只有前三個。其前三個引數分別表示矩陣元素的型別、行數和列數。

         矩陣定義時可以使用Dynamic來表示矩陣的行列數為未知。

         Eigen中無論是矩陣還是陣列、向量,無論是靜態矩陣還是動態矩陣都提供預設建構函式,也就是定義這些資料結構時都可以不用提供任何引數,其大小均由執行時來確定。矩陣的建構函式中只提供行列數、元素型別的構造引數,而不提供元素值的構造,對於比較小的、固定長度的向量提供初始化元素的定義。

         矩陣型別:Eigen中的矩陣型別一般都是用類似MatrixXXX來表示,可以根據該名字來判斷其資料型別,比如”d”表示double型別,”f”表示float型別,”i”表示整數,”c”表示複數;Matrix2f,表示的是一個2*2維的,其每個元素都是float型別。

         資料儲存

:Matrix建立的矩陣預設是按列儲存,Eigen在處理按列儲存的矩陣時會更加高效。如果想修改可以在建立矩陣的時候加入引數,如:

Matrix<int,3, 4, ColMajor> Acolmajor;

Matrix<int,3, 4, RowMajor> Arowmajor;

         動態矩陣和靜態矩陣:動態矩陣是指其大小在執行時確定,靜態矩陣是指其大小在編譯時確定。

         MatrixXd:表示任意大小的元素型別為double的矩陣變數,其大小隻有在執行時被賦值之後才能知道。

         Matrix3d:表示元素型別為double大小為3*3的矩陣變數,其大小在編譯時就知道。

         在Eigen中行優先的矩陣會在其名字中包含有row,否則就是列優先。

         Eigen中的向量只是一個特殊的矩陣,其維度為1而已。

         矩陣元素的訪問:在矩陣的訪問中,行索引總是作為第一個引數,Eigen中矩陣、陣列、向量的下標都是從0開始。矩陣元素的訪問可以通過”()”操作符完成。例如m(2, 3)既是獲取矩陣m的第2行第3列元素。

         針對向量還提供”[]”操作符,注意矩陣則不可如此使用。

         設定矩陣的元素:在Eigen中過載了”<<”操作符,通過該操作符即可以一個一個元素的進行賦值,也可以一塊一塊的賦值。另外也可以使用下標進行賦值。

         重置矩陣大小:當前矩陣的行數、列數、大小可以通過rows()、cols()和size()來獲取,對於動態矩陣可以通過resize()函式來動態修改矩陣的大小。注意:(1)、固定大小的矩陣是不能使用resize()來修改矩陣的大小;(2)、resize()函式會析構掉原來的資料,因此呼叫resize()函式之後將不能保證元素的值不改變;(3)、使用”=”操作符操作動態矩陣時,如果左右兩邊的矩陣大小不等,則左邊的動態矩陣的大小會被修改為右邊的大小。

         如何選擇動態矩陣和靜態矩陣:對於小矩陣(一般大小小於16)使用固定大小的靜態矩陣,它可以帶來比較高的效率;對於大矩陣(一般大小大於32)建議使用動態矩陣。注意:如果特別大的矩陣使用了固定大小的靜態矩陣則可能會造成棧溢位的問題。

         矩陣和向量的算術運算:在Eigen中算術運算過載了C++的+、-、*

         (1)、矩陣的運算:提供+、-、一元操作符”-”、+=、-=;二元操作符+/-,表示兩矩陣相加(矩陣中對應元素相加/減,返回一個臨時矩陣);一元操作符-表示對矩陣取負(矩陣中對應元素取負,返回一個臨時矩陣);組合操作法+=或者-=表示(對應每個元素都做相應操作);矩陣還提供與標量(單一數字)的乘除操作,表示每個元素都與該標量進行乘除操作;

         (2)、求矩陣的轉置、共軛矩陣、伴隨矩陣:可以通過成員函式transpose()、conjugate()、adjoint()來完成。注意:這些函式返回操作後的結果,而不會對原矩陣的元素進行直接操作,如果要讓原矩陣進行轉換,則需要使用響應的InPlace函式,如transpoceInPlace()等;

         (3)、矩陣相乘、矩陣向量相乘:使用操作符*,共有*和*=兩種操作符;

         (4)、矩陣的塊操作:有兩種使用方法:

         matrix.block(i,j, p, q) : 表示返回從矩陣(i, j)開始,每行取p個元素,每列取q個元素所組成的臨時新矩陣物件,原矩陣的元素不變;

         matrix.block<p,q>(i, j) :<p, q>可理解為一個p行q列的子矩陣,該定義表示從原矩陣中第(i, j)開始,獲取一個p行q列的子矩陣,返回該子矩陣組成的臨時矩陣物件,原矩陣的元素不變;

         (5)、向量的塊操作:

         獲取向量的前n個元素:vector.head(n);

         獲取向量尾部的n個元素:vector.tail(n);

         獲取從向量的第i個元素開始的n個元素:vector.segment(i,n);

         Map類:在已經存在的矩陣或向量中,不必拷貝物件,而是直接在該物件的記憶體上進行運算操作。

2.      新建一個vs2013 TestEigen控制檯工程,將Eigen檔案所在目錄加入到工程屬性的C/C++附加包含目錄中,這樣就可以使用Eigen中的函數了;

3.      TestEigen.cpp檔案中的內容為:

[cpp] view plain copy print?在CODE上檢視程式碼片派生到我的程式碼片
  1. #include "stdafx.h"
  2. #include <iostream>
  3. #include <Eigen/Dense>
  4. template <typename T>  
  5. staticvoid matrix_mul_matrix(T* p1, int iRow1, int iCol1, T* p2, int iRow2, int iCol2, T* p3)  
  6. {  
  7.     if (iRow1 != iRow2) return;  
  8.     //列優先
  9.     //Eigen::Map< Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> > map1(p1, iRow1, iCol1);
  10.     //Eigen::Map< Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> > map2(p2, iRow2, iCol2);
  11.     //Eigen::Map< Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> > map3(p3, iCol1, iCol2);
  12.     //行優先
  13.     Eigen::Map< Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> > map1(p1, iRow1, iCol1);  
  14.     Eigen::Map< Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> > map2(p2, iRow2, iCol2);  
  15.     Eigen::Map< Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> > map3(p3, iCol1, iCol2);  
  16.     map3 = map1 * map2;  
  17. }  
  18. int main(int argc, char* argv[])  
  19. {  
  20.     //1. 矩陣的定義
  21.     Eigen::MatrixXd m(2, 2);  
  22.     Eigen::Vector3d vec3d;  
  23.     Eigen::Vector4d vec4d(1.0, 2.0, 3.0, 4.0);  
  24.     //2. 動態矩陣、靜態矩陣
  25.     Eigen::MatrixXd matrixXd;  
  26.     Eigen::Matrix3d matrix3d;  
  27.     //3. 矩陣元素的訪問
  28.     m(0, 0) = 1;  
  29.     m(0, 1) = 2;  
  30.     m(1, 0) = m(0, 0) + 3;   
  31.     m(1, 1) = m(0, 0) * m(0, 1);  
  32.     std::cout << m << std::endl << std::endl;  
  33.     //4. 設定矩陣的元素
  34.     m << -1.5, 2.4,  
  35.         6.7, 2.0;  
  36.     std::cout << m << std::endl << std::endl;  
  37.     int row = 4;  
  38.     int col = 5;  
  39.     Eigen::MatrixXf matrixXf(row, col);  
  40.     matrixXf << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20;  
  41.     std::cout << matrixXf << std::endl << std::endl;  
  42.     matrixXf << Eigen::MatrixXf::Identity(row, col);  
  43.     std::cout << matrixXf << std::endl << std::endl;  
  44.     //5. 重置矩陣大小
  45.     Eigen::MatrixXd matrixXd1(3, 3);  
  46.     m = matrixXd1;  
  47.     std::cout << m.rows() << "  " << m.cols() << std::endl << std::endl;  
  48.     //6. 矩陣運算
  49.     m << 1, 2, 7,  
  50.         3, 4, 8,  
  51.         5, 6, 9;  
  52.     std::cout << m << std::endl;  
  53.     matrixXd1 = Eigen::Matrix3d::Random();  
  54.     m += matrixXd1;  
  55.     std::cout << m << std::endl << std::endl;  
  56.     m *= 2;  
  57.     std::cout << m << std::endl << std::endl;  
  58.     std::cout << -m << std::endl << std::endl;  
  59.     std::cout << m << std::endl << std::endl;  
  60.     //7. 求矩陣的轉置、共軛矩陣、伴隨矩陣
  61.     std::cout << m.transpose() << std::endl << std::endl;  
  62.     std::cout << m.conjugate() << std::endl << std::endl;  
  63.     std::cout << m.adjoint() << std::endl << std::endl;  
  64.     std::cout << m << std::endl << std::endl;  
  65.     m.transposeInPlace();  
  66.     std::cout << m << std::endl << std::endl;  
  67.     //8. 矩陣相乘、矩陣向量相乘
  68.     std::cout << m*m << std::endl << std::endl;  
  69.     vec3d = Eigen::Vector3d(1, 2, 3);  
  70.     std::cout << m * vec3d << std::endl << std::endl;  
  71.     std::cout << vec3d.transpose()*m << std::endl << std::endl;  
  72.     //9. 矩陣的塊操作
  73.     std::cout << m << std::endl << std::endl;  
  74.     std::cout << m.block(1, 1, 2, 2) << std::endl << std::endl;  
  75.     std::cout << m.block<1, 2>(0, 0) << std::endl << std::endl;  
  76.     std::cout << m.col(1) << std::endl << std::endl;  
  77.     std::cout << m.row(0) << std::endl << std::endl;  
  78.     //10. 向量的塊操作
  79.     Eigen::ArrayXf arrayXf(10);  
  80.     arrayXf << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;  
  81.     std::cout << vec3d << std::endl << std::endl;  
  82.     std::cout << arrayXf << std::endl << std::endl;  
  83.     std::cout << arrayXf.head(5) << std::endl << std::endl;  
  84.     std::cout << arrayXf.tail(4) * 2 << std::endl << std::endl;  
  85.     //11. 求解矩陣的特徵值和特徵向量
  86.     Eigen::Matrix2f matrix2f;  
  87.     matrix2f << 1, 2, 3, 4;  
  88.     Eigen::SelfAdjointEigenSolver<Eigen::Matrix2f> eigenSolver(matrix2f);  
  89.     if (eigenSolver.info() == Eigen::Success) {  
  90.         std::cout << eigenSolver.eigenvalues() << std::endl << std::endl;  
  91.         std::cout << eigenSolver.eigenvectors() << std::endl << std::endl;  
  92.     }  
  93.     //12. 類Map及動態矩陣的使用
  94.     int array1[4] = { 1, 2, 3, 4 };  
  95.     int array2[4] = { 5, 6, 7, 8 };  
  96.     int array3[4] = { 0, 0, 0, 0};  
  97.     matrix_mul_matrix(array1, 2, 2, array2, 2, 2, array3);  
  98.     for (int i = 0; i < 4; i++)  
  99.         std::cout << array3[i] << std::endl;  
  100.     return 0;  
  101. }  
save_snippets.png
#include "stdafx.h"
#include <iostream>

#include <Eigen/Dense>

template <typename T>
static void matrix_mul_matrix(T* p1, int iRow1, int iCol1, T* p2, int iRow2, int iCol2, T* p3)
{
    if (iRow1 != iRow2) return;

    //列優先
    //Eigen::Map< Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> > map1(p1, iRow1, iCol1);
    //Eigen::Map< Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> > map2(p2, iRow2, iCol2);
    //Eigen::Map< Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> > map3(p3, iCol1, iCol2);

    //行優先
    Eigen::Map< Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> > map1(p1, iRow1, iCol1);
    Eigen::Map< Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> > map2(p2, iRow2, iCol2);
    Eigen::Map< Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> > map3(p3, iCol1, iCol2);

    map3 = map1 * map2;
}

int main(int argc, char* argv[])
{
    //1. 矩陣的定義
    Eigen::MatrixXd m(2, 2);
    Eigen::Vector3d vec3d;
    Eigen::Vector4d vec4d(1.0, 2.0, 3.0, 4.0);

    //2. 動態矩陣、靜態矩陣
    Eigen::MatrixXd matrixXd;
    Eigen::Matrix3d matrix3d;

    //3. 矩陣元素的訪問
    m(0, 0) = 1;
    m(0, 1) = 2;
    m(1, 0) = m(0, 0) + 3; 
    m(1, 1) = m(0, 0) * m(0, 1);
    std::cout << m << std::endl << std::endl;

    //4. 設定矩陣的元素
    m << -1.5, 2.4,
        6.7, 2.0;
    std::cout << m << std::endl << std::endl;
    int row = 4;
    int col = 5;
    Eigen::MatrixXf matrixXf(row, col);
    matrixXf << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20;
    std::cout << matrixXf << std::endl << std::endl;
    matrixXf << Eigen::MatrixXf::Identity(row, col);
    std::cout << matrixXf << std::endl << std::endl;

    //5. 重置矩陣大小
    Eigen::MatrixXd matrixXd1(3, 3);
    m = matrixXd1;
    std::cout << m.rows() << "  " << m.cols() << std::endl << std::endl;

    //6. 矩陣運算
    m << 1, 2, 7,
        3, 4, 8,
        5, 6, 9;
    std::cout << m << std::endl;
    matrixXd1 = Eigen::Matrix3d::Random();
    m += matrixXd1;
    std::cout << m << std::endl << std::endl;
    m *= 2;
    std::cout << m << std::endl << std::endl;
    std::cout << -m << std::endl << std::endl;
    std::cout << m << std::endl << std::endl;

    //7. 求矩陣的轉置、共軛矩陣、伴隨矩陣
    std::cout << m.transpose() << std::endl << std::endl;
    std::cout << m.conjugate() << std::endl << std::endl;
    std::cout << m.adjoint() << std::endl << std::endl;
    std::cout << m << std::endl << std::endl;
    m.transposeInPlace();
    std::cout << m << std::endl << std::endl;

    //8. 矩陣相乘、矩陣向量相乘
    std::cout << m*m << std::endl << std::endl;
    vec3d = Eigen::Vector3d(1, 2, 3);
    std::cout << m * vec3d << std::endl << std::endl;
    std::cout << vec3d.transpose()*m << std::endl << std::endl;

    //9. 矩陣的塊操作
    std::cout << m << std::endl << std::endl;
    std::cout << m.block(1, 1, 2, 2) << std::endl << std::endl;
    std::cout << m.block<1, 2>(0, 0) << std::endl << std::endl;
    std::cout << m.col(1) << std::endl << std::endl;
    std::cout << m.row(0) << std::endl << std::endl;

    //10. 向量的塊操作
    Eigen::ArrayXf arrayXf(10);
    arrayXf << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
    std::cout << vec3d << std::endl << std::endl;
    std::cout << arrayXf << std::endl << std::endl;
    std::cout << arrayXf.head(5) << std::endl << std::endl;
    std::cout << arrayXf.tail(4) * 2 << std::endl << std::endl;

    //11. 求解矩陣的特徵值和特徵向量
    Eigen::Matrix2f matrix2f;
    matrix2f << 1, 2, 3, 4;
    Eigen::SelfAdjointEigenSolver<Eigen::Matrix2f> eigenSolver(matrix2f);
    if (eigenSolver.info() == Eigen::Success) {
        std::cout << eigenSolver.eigenvalues() << std::endl << std::endl;
        std::cout << eigenSolver.eigenvectors() << std::endl << std::endl;
    }

    //12. 類Map及動態矩陣的使用
    int array1[4] = { 1, 2, 3, 4 };
    int array2[4] = { 5, 6, 7, 8 };
    int array3[4] = { 0, 0, 0, 0};
    matrix_mul_matrix(array1, 2, 2, array2, 2, 2, array3);
    for (int i = 0; i < 4; i++)
        std::cout << array3[i] << std::endl;

	return 0;
}

參考文獻:


相關推薦

Fiddler抓包1_介紹界面概述

緩存 沒有 user 編輯器 主菜單 selected ble bar 文件格式 一、 主要抓包工具介紹與對比 1、Wireshark :通用抓包工具,抓取信息量龐大,需要過濾才能得到有用信息,只抓HTTP請求有點大財小用。 2、Firebug、HttpWatch等We

zookeeperzookeeper介紹安裝和叢集配置

1.什麼是zookeeper ?     zookeeper 英文直譯是動物管理員,試想下,動物園裡有很多動物,如果沒有動物管理員去做管理的話,各種動物混在一起很可能出現打架問題,疾病,髒,等等一系列問題,這個時候就需要有個主人去把這些動物統一管理起來,zookeeper其實

MySQL初識資料庫簡單操作

一、資料庫概述 1.1 什麼是資料(Data) 描述事物的符號記錄稱為資料,描述事物的符號既可以是數字,也可以是文字、圖片,影象、聲音、語言等,資料由多種表現形式,它們都可以經過數字化後存入計算機。 1.2 什麼是資料庫(DataBase,簡稱DB) 資料庫即存放資料的倉庫,只不過這個倉庫是在計算機儲

ZooKeeperZooKeeper安裝簡單操作

centos task spa val jdk8 dir mini dmi 高效 ZooKeeper介紹   ZooKeeper是一個分布式的,開放源碼的分布式應用程序協調服務,是Google的Chubby一個開源的實現,是Hadoop和Hbase的重要組件。它是一個為分布

EigenEigen介紹簡單使用

Eigen是可以用來進行線性代數、矩陣、向量操作等運算的C++庫,它裡面包含了很多演算法。它的License是MPL2。它支援多平臺。          Eigen採用原始碼的方式提供給使用者使用,在使用時只需要包含Eigen的標頭檔案即可進行使用。之所以採用這種方式,是因為Eigen採用模板方式實現,由於

C++小知識(十)——Eigen介紹簡單使用(PCL庫實現)

轉載自:https://blog.csdn.net/fengbingchun/article/details/47378515,          Eigen是可以用來進行線性代數、矩陣、向量操作等運算的C++庫,它裡面包含了很多演算法。它的License是MPL2。它支援

python os檔案庫的簡單介紹和使用

路徑操作 os.path 子庫,用來處理檔案路徑等資訊 使用方法: import os.path import os.path as op # 返回當前檔案絕對路徑 os.path.abspath(path) #歸一化路徑檔案,統一為\\分隔形式 os.path.n

Spring訊息RabbitMq安裝簡單應用(二)

前言: 埋頭苦寫。先把官方文件翻譯過來。整個流程跑一遍。上一篇文章,【Spring訊息】RabbitMq安裝及簡單應用(一),把點對點發送訊息寫完了。之前雖然也可以一個生產者多個消費者,但是一條訊息只能被一個消費者處理,所以是點對點。這篇文章來講講釋出訂閱,一對多。一條訊息

原創Python+Scrapy+Selenium簡單爬取淘寶天貓商品資訊評論

(轉載請註明出處)哈嘍,大家好~前言:這次寫這個小指令碼的目的是為了給老師幫個小忙,爬取某一商品的資訊,寫完覺得這個程式似乎也可以用在更普遍的地方,所以就放出來給大家看看啦,然後因為是在很短時間寫的,所以自然有很多不足之處,想著總之實現了功能再說吧,程式碼太醜大不了之後再重構

高效能Eigen矩陣庫使用事項

1、Eigen庫只有矩陣運算功能。Eigen相對專一,面對四元數、統計、微積分等高階運算功能,我建議還是使用專業的科學運算庫。 2、四階或以下的矩陣,尤其是固定大小的矩陣如Eigen::Matrix2i,通常進行了計算優化。 3、注意一下自身和非自身的變化: 說明

shell編寫一個簡單的jmeter自動化壓測腳本

image tac vbo 用戶數 osx dot png das uvc 在公司做壓力測試也挺長時間了,每次測試前環境數據準備都需要話費較長時間,所以一直在考慮能不能將整個過程實現自動化進行,於是就抽空寫了一個自動化腳本,當然這個腳本目前功能十分簡陋,代碼也不完善,很有很

大數據HDFS部署文件讀寫(包含eclipse hadoop配置)

throw 大數據 我的電腦 ssh 生效 manager 方法 slave .sh 一  原理闡述 1‘  DFS     分布式文件系統(即DFS,Distributed File System),指文件系統管理的物理存儲資源不一定直接連接在本地節點上,而是通過計算機網

PostgreSQL進程體系結構

體系結構 同時 image add 負責 com blog images 後臺 本文主要講述了PG的幾個主要進程,以及PG的核心架構。進程和體系結構詳見下圖: 從上面的體系結構圖可以看出來,PG使用經典的C/S架構,進程架構。在服務器端有主進程、服務進程、子進程、共享

Linux JDK安裝配置 (tar.gz版)

ubuntu logs 環境 pat source alt 修改 8.0 添加 安裝環境   Linux(Ubuntu 版) JDK安裝   tar.gz為解壓後就可以使用的版本,這裏我將使用jdk-8u65-linux-x64.tar.gz版,安裝到/usr/java/下

MongoDB安裝配置

.org root 終端 配置 conn tin serve cal 數據文件 一、MongoDB安裝 1、下載並解壓 wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel62-3.2.0.tgz

Oracle12cWindows安裝、介紹簡單使用(圖文)

enter database cto 應該 技術 功能 自帶 eve 繼續 1、下載 地址為:http://www.oracle.com/technetwork/cn/database/enterprise-edition/downloads/index.html 含企

英語學習-英語簡單句的五種句型結構

morn machine pic day pict usb 情況 fin ack  一、主語+不及物動詞(S+V)   [例句]1. The man cooks. 男人做飯。   2. The sun is shining brightly. 太陽在明亮地照耀著。   3.

Oracle 12c Windows安裝、介紹簡單使用(圖文)

htm 編程 閱讀 arch 用戶 upgrade plsql windows安裝 條件 1、下載 地址為:http://www.oracle.com/technetwork/cn/database/enterprise-edition/downloads/inde

luogu P3808 模板AC自動機(簡單版)

重復 數組 max space length range spa truct ron 題目背景 這是一道簡單的AC自動機模板題。 用於檢測正確性以及算法常數。 為了防止卡OJ,在保證正確的基礎上只有兩組數據,請不要惡意提交。 管理員提示:本題數據內有重復的單詞,且重

Parquet介紹簡單使用

Parquet==> 什麽是parquet Parquet 是列式存儲的一種文件類型==> 官網描述: Apache Parquet is a columnar storage format available to any project in the Ha