強(qiáng)大的C++矩陣處理庫(kù)-Eigen

Eigen介紹

Eigen是可以用來(lái)進(jìn)行線性代數(shù)、矩陣祟偷、向量操作等運(yùn)算的C++庫(kù)察滑,它里面包含了很多算法。它的License是MPL2修肠。它支持多平臺(tái)贺辰。使用類(lèi)似Matlab的方式操作矩陣,單純講和Matlab的對(duì)應(yīng)的話,可能不如Armadillo(http://arma.sourceforge.net/)對(duì)應(yīng)的好饲化,但功能絕對(duì)強(qiáng)大莽鸭。
Eigen包含了絕大部分你能用到的矩陣算法,同時(shí)提供許多第三方的接口吃靠。Eigen一個(gè)重要特點(diǎn)是采用源碼的方式提供給用戶使用蒋川,在使用時(shí)只需要包含Eigen的頭文件即可進(jìn)行使用。之所以采用這種方式撩笆,是因?yàn)镋igen采用模板方式實(shí)現(xiàn)捺球,由于模板函數(shù)不支持分離編譯,所以只能提供源碼而不是動(dòng)態(tài)庫(kù)的方式供用戶使用夕冲,因此非常輕量而易于跨平臺(tái)氮兵。你要做的就是把用到的頭文件和你的代碼放在一起就可以了。

Eigen的一些特性:

  • 支持整數(shù)歹鱼、浮點(diǎn)數(shù)泣栈、復(fù)數(shù),使用模板編程弥姻,可以為特殊的數(shù)據(jù)結(jié)構(gòu)提供矩陣操作南片。比如在用ceres-solver進(jìn)行做優(yōu)化問(wèn)題(比如bundle adjustment)的時(shí)候,有時(shí)候需要用模板編程寫(xiě)一個(gè)目標(biāo)函數(shù)庭敦,ceres可以將模板自動(dòng)替換為內(nèi)部的一個(gè)可以自動(dòng)求微分的特殊的double類(lèi)型疼进。而如果要在這個(gè)模板函數(shù)中進(jìn)行矩陣計(jì)算,使用Eigen就會(huì)非常方便秧廉。
  • 支持逐元素伞广、分塊、和整體的矩陣操作疼电。
  • 內(nèi)含大量矩陣分解算法包括LU嚼锄,LDLt,QR蔽豺、SVD等等区丑。
  • 支持使用Intel MKL加速
  • 部分功能支持多線程
  • 稀疏矩陣支持良好,到今年新出的Eigen3.3修陡,已經(jīng)自帶了SparseLU沧侥、SparseQR、共軛梯度(ConjugateGradient solver)濒析、bi conjugate gradient stabilized solver等解稀疏矩陣的功能正什。同時(shí)提供SPQR啥纸、UmfPack等外部稀疏矩陣庫(kù)的接口号杏。
  • 支持常用幾何運(yùn)算,包括旋轉(zhuǎn)矩陣、四元數(shù)盾致、矩陣變換主经、AngleAxis(歐拉角與Rodrigues變換)等等。
  • 更新活躍庭惜,用戶眾多(Google罩驻、WilliowGarage也在用),使用Eigen的比較著名的開(kāi)源項(xiàng)目有ROS(機(jī)器人操作系統(tǒng))护赊、PCL(點(diǎn)云處理庫(kù))惠遏、Google Ceres(優(yōu)化算法)。OpenCV自帶到Eigen的接口骏啰。
    總體來(lái)講节吮,如果經(jīng)常做一些比較復(fù)雜的矩陣計(jì)算的話,或者想要跨平臺(tái)的話判耕,非常值得一用透绩。

Eigen是C++中可以用來(lái)調(diào)用并進(jìn)行矩陣計(jì)算的一個(gè)庫(kù),里面封裝了一些類(lèi)壁熄,需要的頭文件和功能如下:

Eigen的主頁(yè)上有一些更詳細(xì)的Eigen介紹帚豪。

Eigen的下載

這里是官網(wǎng)主頁(yè),可自行下載需要的版本草丧,是個(gè)code包狸臣,不用安裝。

Eigen的配置

這里以VS2015為例昌执,C/C++ -> Additional Include Directories填上Eigen解壓文件夾的位置即可固棚,也可將文件夾放在Solution目錄下,寫(xiě)作:$(SolutionDir)\eigen3

Eigen:矩陣(Matrix)類(lèi)的介紹及使用

在Eigen中仙蚜,所有矩陣和向量均為Matrix模板類(lèi)的對(duì)象此洲,向量是矩陣的行(或列)為1是的特殊情況。

1委粉、矩陣的三參數(shù)模板
Matrix類(lèi)有六個(gè)模板參數(shù)呜师,其中三個(gè)有默認(rèn)值,因此只要學(xué)習(xí)三個(gè)參數(shù)就足夠了贾节。

/* 強(qiáng)制性的三參數(shù)模板的原型 (三個(gè)參數(shù)分別表示:標(biāo)量的類(lèi)型汁汗,編譯時(shí)的行,編譯時(shí)的列) */
Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime> 

/* 用typedef定義了很多模板栗涂,例如:Matrix4f 表示 4×4 的floats 矩陣 */ 
typedef Matrix<float, 4, 4> Matrix4f;

2知牌、向量(Vectors)
向量是矩陣的特殊情況,也是用矩陣定義的斤程。

typedef Matrix<float, 3, 1> Vector3f;  
typedef Matrix<int, 1, 2> RowVector2i;

3角寸、特殊動(dòng)態(tài)值(special value Dynamic)
Eigen的矩陣不僅能夠在編譯是確定大衅谢臁(fixed size),也可以在運(yùn)行時(shí)確定大小扁藕,就是所說(shuō)的動(dòng)態(tài)矩陣(dynamic size)沮峡。

typedef Matrix<double, Dynamic, Dynamic> MatrixXd;  
typedef Matrix<int, Dynamic, 1> VectorXi;  

/* 也可使用‘行’固定‘列’動(dòng)態(tài)的矩陣 */
Matrix<float, 3, Dynamic>

4、構(gòu)造函數(shù)(Constructors)
可以使用默認(rèn)的構(gòu)造函數(shù)亿柑,不執(zhí)行動(dòng)態(tài)分配內(nèi)存邢疙,也沒(méi)有初始化矩陣參數(shù):

Matrix3f a;   // a是3-by-3矩陣,包含未初始化的 float[9] 數(shù)組
MatrixXf b;   // b是動(dòng)態(tài)矩陣望薄,當(dāng)前大小為 0-by-0, 沒(méi)有為數(shù)組的系數(shù)分配內(nèi)存

/* 矩陣的第一個(gè)參數(shù)表示“行”疟游,數(shù)組只有一個(gè)參數(shù)。根據(jù)跟定的大小分配內(nèi)存痕支,但不初始化 */
MatrixXf a(10,15);    // a 是10-by-15陣乡摹,分配了內(nèi)存,沒(méi)有初始化
VectorXf b(30);       // b是動(dòng)態(tài)矩陣采转,當(dāng)前大小為 30, 分配了內(nèi)存聪廉,沒(méi)有初始化

/* 對(duì)于給定的矩陣,傳遞的參數(shù)無(wú)效 */
Matrix3f a(3,3); 

/* 對(duì)于維數(shù)最大為4的向量故慈,可以直接初始化 */
Vector2d a(5.0, 6.0);  
Vector3d b(5.0, 6.0, 7.0);  
Vector4d c(5.0, 6.0, 7.0, 8.0);

5板熊、系數(shù)訪問(wèn)
系數(shù)都是從0開(kāi)始,矩陣默認(rèn)按列存儲(chǔ)

#include <iostream>
#include <Eigen/Dense>
using namespace std;
using namespace Eigen;

int main()
{
    MatrixXd m(2, 2);
    m(0, 0) = 3;
    m(1, 0) = 2.5;
    m(0, 1) = -1;
    m(1, 1) = m(1, 0) + m(0, 1);
    cout << "Here is the matrix m:" << endl;
    cout << m << endl;

    VectorXd v(2);
    v(0) = 4;
    v[1] = v[0] - 1;     //operator[] 在 vectors 中重載察绷,意義和()相同
    cout << "Here is the vector v:" << endl;
    cout << v << endl;

    getchar();
    getchar();
}

6干签、逗號(hào)分隔的初始化

Matrix3f m;
m << 1, 2, 3,   4, 5, 6,   7, 8, 9;
cout << m;

7、Resizing
可以用rows(), cols() and size() 改變現(xiàn)有矩陣的大小拆撼。這些類(lèi)方法返回行容劳、列、系數(shù)的數(shù)值闸度。也可以用resize()來(lái)改變動(dòng)態(tài)矩陣的大小竭贩。

test代碼

#include <iostream>  
#include "Eigen/Eigen"  
using namespace std;  
using namespace Eigen;  
  
void foo(MatrixXf& m)  
{  
    Matrix3f m2=Matrix3f::Zero(3,3);  
    m2(0,0)=1;  
    m=m2;  
}  
int main()  
{  
    /* 定義,定義時(shí)默認(rèn)沒(méi)有初始化莺禁,必須自己初始化 */  
    MatrixXf m1(3,4);   //動(dòng)態(tài)矩陣留量,建立3行4列。  
    MatrixXf m2(4,3);   //4行3列哟冬,依此類(lèi)推楼熄。  
    MatrixXf m3(3,3);  
    Vector3f v1;        //若是靜態(tài)數(shù)組,則不用指定行或者列  
    /* 初始化 */  
    m1 = MatrixXf::Zero(3,4);       //用0矩陣初始化,要指定行列數(shù)  
    m2 = MatrixXf::Zero(4,3);  
    m3 = MatrixXf::Identity(3,3);   //用單位矩陣初始化  
    v1 = Vector3f::Zero();          //同理浩峡,若是靜態(tài)的可岂,不用指定行列數(shù)  
  
    m1 << 1,0,0,1,        //也可以以這種方式初始化  
        1,5,0,1,  
        0,0,9,1;  
    m2 << 1,0,0,  
        0,4,0,  
        0,0,7,  
        1,1,1;  
      
    /* 元素的訪問(wèn) */  
    v1[1] = 1;  
    m3(2,2) = 7;  
    cout<<"v1:\n"<<v1<<endl;  
    cout<<"m3:\n"<<m3<<endl;  
    /* 復(fù)制操作 */  
    VectorXf v2=v1;             //復(fù)制后,行數(shù)與列數(shù)和右邊的v1相等,matrix也是一樣,  
                                //也可以通過(guò)這種方式重置動(dòng)態(tài)數(shù)組的行數(shù)與列數(shù)  
    cout<<"v2:\n"<<v2<<endl;  
  
    /* 矩陣操作翰灾,可以實(shí)現(xiàn) + - * / 操作缕粹,同樣可以實(shí)現(xiàn)連續(xù)操作(但是維數(shù)必須符合情況), 
    如m1,m2,m3維數(shù)相同,則可以m1 = m2 + m3 + m1; */  
    m3 = m1 * m2;  
    v2 += v1;  
    cout<<"m3:\n"<<m3<<endl;  
    cout<<"v2:\n"<<v2<<endl;  
    //m3 = m3.transpose();  這句出現(xiàn)錯(cuò)誤稚茅,估計(jì)不能給自己賦值  
    cout<<"m3轉(zhuǎn)置:\n"<<m3.transpose()<<endl;  
    cout<<"m3行列式:\n"<<m3.determinant()<<endl;  
    m3 = m3.inverse();  
    cout<<"m3求逆:\n"<<m3<<endl;  
  
    system("pause");  
  
    return 0;  
}  

本文同時(shí)發(fā)布在個(gè)人主頁(yè)fangda.me上。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末致开,一起剝皮案震驚了整個(gè)濱河市峰锁,隨后出現(xiàn)的幾起案子萎馅,更是在濱河造成了極大的恐慌双戳,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,729評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件糜芳,死亡現(xiàn)場(chǎng)離奇詭異飒货,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)峭竣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)塘辅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人皆撩,你說(shuō)我怎么就攤上這事扣墩。” “怎么了扛吞?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,461評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵呻惕,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我滥比,道長(zhǎng)亚脆,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,135評(píng)論 1 300
  • 正文 為了忘掉前任盲泛,我火速辦了婚禮濒持,結(jié)果婚禮上硼婿,老公的妹妹穿的比我還像新娘不见。我一直安慰自己,他們只是感情好泊愧,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,130評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布村视。 她就那樣靜靜地躺著由境,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蓖议。 梳的紋絲不亂的頭發(fā)上虏杰,一...
    開(kāi)封第一講書(shū)人閱讀 52,736評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音勒虾,去河邊找鬼纺阔。 笑死,一個(gè)胖子當(dāng)著我的面吹牛修然,可吹牛的內(nèi)容都是我干的笛钝。 我是一名探鬼主播质况,決...
    沈念sama閱讀 41,179評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼玻靡!你這毒婦竟也來(lái)了结榄?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 40,124評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤囤捻,失蹤者是張志新(化名)和其女友劉穎臼朗,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體蝎土,經(jīng)...
    沈念sama閱讀 46,657評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡视哑,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,723評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了誊涯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挡毅。...
    茶點(diǎn)故事閱讀 40,872評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖暴构,靈堂內(nèi)的尸體忽然破棺而出跪呈,到底是詐尸還是另有隱情,我是刑警寧澤取逾,帶...
    沈念sama閱讀 36,533評(píng)論 5 351
  • 正文 年R本政府宣布耗绿,位于F島的核電站,受9級(jí)特大地震影響菌赖,放射性物質(zhì)發(fā)生泄漏缭乘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,213評(píng)論 3 336
  • 文/蒙蒙 一琉用、第九天 我趴在偏房一處隱蔽的房頂上張望堕绩。 院中可真熱鬧,春花似錦邑时、人聲如沸奴紧。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,700評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)黍氮。三九已至,卻和暖如春浅浮,著一層夾襖步出監(jiān)牢的瞬間沫浆,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,819評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工滚秩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留专执,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,304評(píng)論 3 379
  • 正文 我出身青樓郁油,卻偏偏與公主長(zhǎng)得像本股,于是被迫代替她去往敵國(guó)和親攀痊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,876評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容