1. 程式人生 > >【1.1】Eigen C++ 矩陣開源庫學習之稠密矩陣和陣列操作——矩陣類

【1.1】Eigen C++ 矩陣開源庫學習之稠密矩陣和陣列操作——矩陣類

稠密矩陣和陣列操作 http://eigen.tuxfamily.org/dox-devel/group__DenseMatrixManipulation__chapter.html
包含模組:
1.矩陣類
2.矩陣和向量的運算
3.陣列操作
4.塊操作
5.高階的初始化
6.減少,訪客和廣播
7.與原始緩衝區介面:Map類
8.重塑和切片
9.別名
10.儲存方式
11.對齊問題
12.參考
13.係數智慧函式的目錄
14.快速參考指南

矩陣類

在Eigen中,所有的矩陣和向量都是Matrix模板類的物件

。向量只是矩陣的一個特例,有1行或1列。

1.Matrix的前三個模板引數

Matrix矩陣類需要六個模板引數,但現在主需要掌握前三個引數即可。剩下的三個引數都有預設值。

Matrix的三個強制模板引數是:

    Matrix < typename Scalar,int RowsAtCompileTime,int ColsAtCompileTime>
  • Scalar是標量型別,即係數的型別。也就是說,如果你想要一個浮動矩陣,請在這裡選擇float。(有關所有支援的標量型別的列表以及如何將支援擴充套件到新型別的資訊,請參閱標量型別http://eigen.tuxfamily.org/dox-devel/TopicScalarTypes.html

    )。

  • RowsAtCompileTimeColsAtCompileTime是編譯時已知的矩陣的行數和列數(如果在編譯時不知道該數字,請參閱下面的內容)。
    我們提供了很多方便的typedef來覆蓋常見的情況。
    例如,Matrix4f是一個4x4的浮點矩陣。Eigen定義如下:

typedef Matrix <float44> Matrix4f ;

我們在下面討論這些便利的typedef。

2.向量

如上所述,在Eigen中,向量只是矩陣的一個特例,有1行或1列
他們有1列的情況是最常見的; 這樣的向量被稱為列向量,通常簡稱為向量。
在另一個有1行的情況下,它們被稱為行向量

例如,便捷typedef Vector3f是3個浮點數的(列)向量。Eigen定義如下:

typedef Matrix <float31> Vector3f ;

我們還為行向量提供便利的typedef,例如:

typedef Matrix <int1,2> RowVector2i ;

3.特殊值Dynamic

當然,Eigen不限於在編譯時已知尺寸的矩陣。在RowsAtCompileTime和ColsAtCompileTime模板引數可以採取特殊值Dynamic這表明大小在編譯時是未知的,所以必須作為執行時變數來處理。

在特徵術語中,這樣的尺寸被稱為動態尺寸 ; 而編譯時已知的大小稱為固定大小
例如,typedef MatrixXd,意思是動態大小的double矩陣,定義如下:

typedef Matrix <double,DynamicDynamic> MatrixXd ;

同樣,我們定義一個不言自明的typedef VectorXi如下:

typedef Matrix <int,Dynamic,1> VectorXi ;

您可以完美地擁有固定行數,動態列數的矩陣,如下所示:

Matrix <float3,Dynamic>

4.建構函式

不帶參的建構函式(預設),不會執行任何動態的記憶體分配,也不會初始化矩陣係數。你可以這樣定義:

Matrix3f a;     
MatrixXf b;

這裡,
- a 是一個3乘3的矩陣,具有9個未初始化係數的普通浮點數陣列。
- b 是一個動態大小的矩陣,其大小當前為0,係數陣列的大小沒有被分配。

帶參的建構函式
對於矩陣,行在前,列在後。
對於向量,只需傳遞向量的大小。
他們分配具有給定大小的係數陣列,但不會初始化係數本身:

MatrixXf a10,15;
VectorXf b(30;

這裡,
- a 是一個10x15的動態矩陣,具有已分配大小但目前未初始化的係數。
- b 是一個大小為30的動態大小的向量,具有已分配但目前未初始化的係數。

為了給固定大小和動態大小的矩陣中提供統一的API,在固定大小的矩陣上使用這些建構函式也是合法的,即使在這種情況下通過大小是無效的。以下是合法的,雖然是個空操作:

Matrix3f a3,3;

最後,我們還提供了一些建構函式來初始化尺寸為4的小型固定尺寸向量的係數:

Vector2d a5.06.0;
Vector3d b(5.06.07.0;
Vector4d c(5.06.07.08.0;

5.引數訪問

Eigen中的主要引數訪問和儲存的方式是過載的 ==括號操作符==
對於矩陣,行索引總是先傳遞。對於向量,只需傳遞一個索引。編號從0開始。這個例子是不言自明的:

#include <iostream>
#include <Eigen/Dense>
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);
  std :: cout << “矩陣m:\ n” << m << std :: endl;
  VectorXd v(2);
  v(0)= 4;
  v(1)= v(0)-1;
  std :: cout << “向量v:\ n” << v << std :: endl;
}

/*
output:
矩陣m:
 3   -1
2.5  1.5
向量v:
4
3
*/

vector[]也被過載,用於向量中的基於索引的訪問,但請記住,C++不允許operator []使用多個引數。所以我們限制運算子[]作用於向量而不用於矩陣,因為C ++語言會尷尬地將將矩陣[i,j]編譯為與矩陣[j]相同的東西!

6.逗號初始化

矩陣和向量係數可以使用 ==逗號初始化== 語法方便地設定。現在,知道這個例子就足夠了:

Matrix3f m;     //定義一個3*3矩陣,使用逗號初始化.
m << 123456789;
std :: cout << m;
/*
輸出:
1 2 3
4 5 6
7 8 9
*/

7.調整矩陣大小

矩陣的當前大小可以通過rows(),cols()和size()來檢索
這些方法分別返回行數,列數和係數個數
==調整動態大小矩陣的大小由resize()== 方法完成。

#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
int main()
{
  MatrixXd m(2,5);      //矩陣m原來的大小為2*5
  m.resize(4,3);        //通過resize函式將大小改為4*3
  std::cout << "矩陣m的大小為:"
            << m.rows() << "x" << m.cols() << std::endl;
  std::cout << "擁有" << m.size() << "個係數" << std::endl;
  VectorXd v(2);
  v.resize(5);
  std::cout << "向量v的大小為:" << v.size() << std::endl;
  std::cout << "按照矩陣來看,v的大小為: "
            << v.rows() << "x" << v.cols() << std::endl;
}
/*
output:
矩陣m的大小是4×3
它有12個係數
向量v的大小為5
按照矩陣來看,v的大小是5x1
*/

如果實際的矩陣大小沒有改變,resize()方法是無操作的; 否則是破壞性的:係數的值可能會改變。如果你想要一個不改變係數的resize()的保守方法,使用conservativeResize(),更多細節見本頁http://eigen.tuxfamily.org/dox-devel/TopicResizing.html

所有這些方法仍然可用於固定尺寸的矩陣,為了API的一致性。當然,你實際上不能調整固定大小的矩陣。嘗試將固定大小更改為實際不同的值將觸發斷言失敗; 但下面的程式碼是合法的:

#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
int main()
{
  Matrix4d m;
  m.resize(4,4); // 無效,但是合法
  std::cout << "矩陣m的大小為: "
            << m.rows() << "x" << m.cols() << std::endl;
}

//output : 矩陣m的大小是4×4

7.分配和調整大小

賦值操作operator=是將矩陣複製到另一個矩陣中的。Eigen ==自動調整左側矩陣的大小==,使其與右側矩陣的大小相匹配。

MatrixXf a(2,2);
std::cout << "a is of size " << a.rows() << "x" << a.cols() << std::endl;
MatrixXf b(3,3);
a = b;
std::cout << "a is now of size " << a.rows() << "x" << a.cols() << std::endl

8.固定大小與動態大小的選擇

什麼時候應該使用固定大小(例如Matrix4f),什麼時候更適合動態大小(例如MatrixXf)
簡單的答案是:在允許的情況下使用固定的尺寸來實現非常小的尺寸,而對於更大的尺寸或者必須使用動態的尺寸則用動態大小
對於小尺寸,特別是對於尺寸小於(或等於)16的尺寸,使用固定尺寸對效能非常有利,因為它允許Eigen避免動態記憶體分配並展開迴圈
在內部,一個固定大小的特徵矩陣只是一個普通的陣列,也就是

Matrix4f mymatrix;

相當於

float mymatrix [16];

所以這確實具有零執行成本。
相比之下,動態大小矩陣的陣列總是分配在堆上

MatrixXf mymatrix(rows, columns);

相當於做

float * mymatrix = new  float [rows * columns];

除此之外,MatrixXf物件將其行數和列數儲存為成員變數。

當然,使用固定大小的限制是,只有在編譯時知道大小的情況下才可以。而且,對於尺寸大於(大致)32的足夠大的尺寸而言,使用固定尺寸的效能益處變得可以忽略不計。更糟糕的是,試圖在函式中使用固定大小建立一個非常大的矩陣可能會導致堆疊溢位,因為Eigen會嘗試自動分配陣列作為區域性變數,而這通常是在堆疊中完成的。
最後,根據情況,當使用動態大小時,Eigen也可以更積極地嘗試向量化(使用SIMD指令),參見向量化(http://eigen.tuxfamily.org/dox-devel/TopicVectorization.html)。

9.可選的模板引數

我們在本頁開頭提到,Matrix類有六個模板引數,但到目前為止我們只討論了前三個。其餘三個引數是可選的。以下是模板引數的完整列表:

Matrix<typename Scalar,
       int RowsAtCompileTime,
       int ColsAtCompileTime,
       int Options = 0,
       int MaxRowsAtCompileTime = RowsAtCompileTime,
       int MaxColsAtCompileTime = ColsAtCompileTime>
  • Options是一個位域。在這裡,我們只討論一點:RowMajor。它指定這種型別的矩陣使用行主儲存順序; 預設情況下,儲存順序是以列為主。檢視前面給出的 ==儲存方式選擇==。例如,這種型別意味著以行為豬的主3×3矩陣:
Matrix <float33,RowMajor>
  • MaxRowsAtCompileTime和MaxColsAtCompileTime也可以指定,即使矩陣的確切大小不知道,在編譯時可以自己==制定上限==。這樣做的最大原因是為了避免動態記憶體分配。例如,下面的矩陣型別使用一個12浮點數的普通陣列,而沒有動態記憶體分配:
Matrix <float,DynamicDynamic034>

10.便捷的typedefs

Eigen定義了以下Matrix typedef:

  • MatrixNt等價於Matrix < type,N,N>。例如,MatrixXi可表示Matrix < int,Dynamic,Dynamic>。
  • VectorNt為矩陣< type,N,1>。例如,Vector2f可表示Matrix < float,2,1>,。
  • RowVectorNt用於Matrix < type,1,N>。例如,RowVector3d可表示Matrix < double,1,3>。

其中:
- N可以是任何一個2,3,4,或X(意思Dynamic)。
- t可以是i(意思是int),f(意思是float),d(意思是double),cf(意思是複雜的)或cd(意思是複雜的)中的任何一個。

2018.01.20

相關推薦

1.1Eigen C++ 矩陣開源學習稠密矩陣陣列操作——矩陣

稠密矩陣和陣列操作 http://eigen.tuxfamily.org/dox-devel/group__DenseMatrixManipulation__chapter.html 包含模組: 1.矩陣類 2.矩陣和向量的運算

java版資料結構與演算法分析學習前言

一.資料結構和演算法概述?【框範圍】 基礎資料結構主要包括表【陣列+連結串列】、棧、佇列【散列表】、樹、圖、堆。高階資料結構包括伸展樹、紅黑樹、確定性跳躍表、AA樹、treap樹、k-d樹、配對堆。

Camera專題-從零開始的Camera學習路——啟動篇

1.吐槽 如今工作也一年多了,在現在的公司是啥都除錯,從EMMC,TP,LCD,CAMERA等等,對於底層驅動也有了一定的認識

算法Dijkstra算法(單源最短路徑問題) 鄰接矩陣鄰接表實現

當前 prior 排序 發的 單源最短路徑 fine emp eat col Dijkstra算法可使用的前提:不存在負圈。 負圈:負圈又稱負環,就是說一個全部由負權的邊組成的環,這樣的話不存在最短路,因為每在環中轉一圈路徑總長就會邊小。 算法描述:   1.找到最

Visual StudioVisual C# 中XML註釋的使用(含註釋在開發時顯示換行)

title visual toc sum .net art detail 段落 結構 為函數方法註釋說明要用到 xml 語句 <summary> 段落說明 </summary> 、<para> 新段示例說明 </para>、&

1.C語言指針學習外掛篇

註入 fan font back 編程 int export size col 學習了c語言的指針,那麽指針能做什麽呢,首先,他可以寫外掛 首先我們來編寫一個dll,掛載到植物大戰僵屍上,記住是dll,因為如果你創建一個應用程序,該應用程序是不能操作其他程序的地址的.

編程珠璣第二章問題C

word 保存 隨著 main arc 清晰 詞典 temp 不可 變位詞(anagrams):指的是組成兩個單詞的字符相同,但位置不同的單詞。比如說,abbcd和abcdb就是一對變位詞。在介紹問題c之前,我們先看看如何判斷兩個字符串是否是變位詞。 分析:求解題目C有兩種

閱讀筆記C程序員 從校園到職場》第二章 學校到職場

-c 是什麽 閱讀 括號 blog 能力 出現 而是 pos 一、代碼規範: 1、變量命名(讓人一眼看它是什麽意思,要做什麽操作),定義並初始化 2、函數命名規範(函數的功能)在主函數之前進行聲明。 在實際項目中,一般不在函數調用者的內部來對被調函數進行聲明,而是將聲明放在

閱讀筆記C程序員 從校園到職場》第三章 程序的樣式(大括號)

突出 char s 結構體 需要 初始化 detail 處理 思維 https 參考: https://blog.csdn.net/zhouzhaoxiong1227/article/details/22820533 一、.初始化數組變量 在實際的軟件開

閱讀筆記C程序員 從校園到職場》第六章 配置文件,makefile 文件 (Part 2)

不同 tpc 閱讀 ret ftp 理解 源代碼 exe tst Contents: 1.配置文件(通常以 ini 結尾) 2.makefile文件 (Linux) PS: 這篇文章的內容,不太理解。 一、配置文件 本文以一個實際的小軟件為例,介紹了C語言中配

設計開發 Linux C文件創建Open函數

include == code pan lin his class trunc types.h #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>

二分答案Problem C:木材加工

+= spa 都是 space amp 表示 put 兩個 ret Problem C:木材加工 Time Limit:1000MS Memory Limit:65536K Total Submit:48 Accepted:20 Description 【問題描述】

轉載一個c程序在執行main函數之前main之後都做了那些事情

loss -- text ould 很多 int win 部分 不知道 轉自:https://bbs.csdn.net/topics/300103318#r_78088969 main函數之前--真正的函數執行入口或開始一種解釋實際上,在可執行文件被加載之後,控制權立即交給

FastReport教程介紹C#中的非同步程式設計(下)

【下載FastReport.Netdownload最新版本】 非同步程式設計模型出現在.Net Framework的第一個版本中。APM允許使用兩種方法建立同步方法的非同步版本 - Begin 和End 。 所以,只有兩種方法: public IAsyncResult Begin{MethodName}(

CodeForces - 1034BLittle C Loves 3 II

@Little C Loves 3 [email protected] @題目描述 - [email protected] @中文題意@ @分析@ @程式碼@ @[email protected

[開源學習] Numpy日記 Section.1

前言    最近開始學習Data anaysis,將numpy入門學習日記分享出來,也當做個記錄。  【Numpy官網學習地址】:Click Here    備註:       &nb

修煉C++基礎知識點筆記-第3章 字串,向量陣列

重新學習c++的東西,此為《C++ Primer》讀書筆記,主要記錄零碎的知識。另外所有的C++11新標準也會被列出。 1,位於標頭檔案的程式碼一般來說不應該使用using宣告。這是因為標頭檔案的內容會拷貝到所有引用它的檔案中。 2,拷貝 初始化,直接初始化。【???】 3,stri

順序表C環境下,函式傳遞的指標指向報錯及解決

之前開始學順序表的時候,就沒有很好地弄懂,函式裡指標的傳遞這一塊,今天把錯誤範例和一些解決方式拿出來分析一下。 網上有很多掛羊頭賣狗肉的c語言教程,函式是引用呼叫的,就很誤導人。 Wrong: typedef struct { int *elem; in

2018.10.24校內模擬C 的序列(數論)(連結串列)

傳送門 解析: 本來可以拿80pts80pts80pts暴力的 然後unorderedmap−&gt;mapunordered\text{ }map-&gt;mapunorderedmap−>map,−20pts-20pts−20pts

博物納新2D破碎效果開源測評

【博物納新】是UWA重磅推出的全新欄目,旨在為開發者推薦新穎、易用、有趣的開源專案,幫助大家在專案研發之餘發現世界上的熱門專案、前沿技術或者令人驚歎的視覺效果,並探索將其應用到自己專案的可行性。很多時候