日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

Eigen入门之密集矩阵 7 - Map class:连接Eigen与C++的数据

發(fā)布時(shí)間:2023/12/15 c/c++ 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Eigen入门之密集矩阵 7 - Map class:连接Eigen与C++的数据 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

簡(jiǎn)介

本文介紹一下Dense Matrix如何與c/C++的數(shù)組進(jìn)行交互操作,這在引入其他的庫(kù)中的vector向量和矩陣到Eigen中時(shí)要使用到的技術(shù)。

有時(shí),你有一些定義好的數(shù)據(jù),可能是數(shù)組,你需要在Eigen內(nèi)使用它。一個(gè)可選的方法是你拷貝一份數(shù)據(jù),在添加到Eigen中,這樣會(huì)有些工程的問(wèn)題,數(shù)據(jù)的一致性等問(wèn)題。幸運(yùn)的是,Eigen內(nèi)為此提供了Map類(lèi),提供了便利的使用方法。

Map在Eigen的四元數(shù)quarternion、排列permutation等都有應(yīng)用。

Map類(lèi)型及變量

在Eigen內(nèi),Map對(duì)象的模板類(lèi)型定義如下:

Map<Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime> >

構(gòu)造器

首先,需要了解的一點(diǎn)是: Map沒(méi)有缺省的構(gòu)造器。這里使用示例來(lái)介紹Map的變量定義/構(gòu)造方法。

要構(gòu)造一個(gè)Map變量,需要提供另外的2個(gè)其他的信息給Eigen: 想要得到的具體的矩陣或者向量、一個(gè)指向存儲(chǔ)了系數(shù)的數(shù)組的地址指針。比如,要定義一個(gè)編譯時(shí)即知道尺寸大小的浮點(diǎn)矩陣,其中pf是一個(gè)指向浮點(diǎn)類(lèi)型數(shù)組的指針??梢赃@樣做:

Map<MatrixXf> mf(pf,rows,columns);

一個(gè)固定尺寸大小的只讀整形向量的Map類(lèi)型,可以通過(guò)一個(gè)int * p指針,通過(guò)構(gòu)造器,這樣定義:
Map<const Vector4i> mi(pi);
在這里,看起來(lái)沒(méi)有傳遞給構(gòu)造器尺寸大小,這是因?yàn)橐呀?jīng)在模板參數(shù)Vector4i中隱含指定了。

類(lèi)Map提供了足夠的靈活性,以滿足多種數(shù)據(jù)形式。這里提供了有2個(gè)模板參數(shù)的定義:

Map<typename MatrixType,int MapOptions,typename StrideType>

這里簡(jiǎn)單介紹一下:

  • MapOptions: 指定指針是否對(duì)齊(Aligned),或者不對(duì)齊(Unaligned);缺省值為不對(duì)齊(Unaligned)。
  • StrideType: 讓使用者指定內(nèi)存中數(shù)組的布局,類(lèi)型為class Stride。下面的例子指定其數(shù)據(jù)數(shù)組使用行優(yōu)先(row-major)格式。

示例:

//matrix_map1.cpp #include <iostream> #include <Eigen/Dense>using namespace std; using namespace Eigen;int main() {int array[9];for(int i = 0; i < 9; ++i) array[i] = i;Map<VectorXi> vi(array,9);Map<const Vector4i> fixed_v(array); // unknown type name 'Vector5i' -- 這種模式size不能大于4cout<< "vector vi: "<< endl << vi << endl<< endl;cout<< "fixed-vector : "<< endl << fixed_v << endl<< endl;cout << "Column-major:\n" << Map<Matrix<int,2,4> >(array) << endl;cout << "Row-major:\n" << Map<Matrix<int,2,4,RowMajor> >(array) << endl;cout << "Row-major using stride:\n" <<Map<Matrix<int,2,4>, Unaligned, Stride<1,4> >(array) << endl; }

執(zhí)行結(jié)果:

$ g++ -I /usr/local/include/eigen3 matrix_map1.cpp -o matrix_map1 $ ./matrix_map1 vector vi: 0 1 2 3 4 5 6 7 8fixed-vector : 0 1 2 3Column-major: 0 2 4 6 1 3 5 7 Row-major: 0 1 2 3 4 5 6 7 Row-major using stride: 0 1 2 3 4 5 6 7

從結(jié)果可以看到,Map()進(jìn)行映射時(shí),缺省時(shí)列有先column-major,或者安裝Eigen中的設(shè)定執(zhí)行。

其實(shí), Stride提供了更大的靈活性,具體信息可以查詢Map和Stride的說(shuō)明文檔。

使用Map變量

對(duì)Map變量的使用,就和其映射的類(lèi)型一致。比如Map到一個(gè)矩陣,則和使用矩陣對(duì)象一樣。如果是向量,則按照向量的類(lèi)型進(jìn)行訪問(wèn)。

直接看Eigen中的示例。

//matrix_map2.cpp #include <iostream> #include <Eigen/Dense>using namespace std; using namespace Eigen;typedef Matrix<float,1,Dynamic> MatrixType; typedef Map<MatrixType> MapType; typedef Map<const MatrixType> MapTypeConst; // a read-only map const int n_dims = 5;int main() {MatrixType m1(n_dims), m2(n_dims);m1.setRandom();m2.setRandom();float *p = &m2(0); // get the address storing the data for m2MapType m2map(p,m2.size()); // m2map shares data with m2MapTypeConst m2mapconst(p,m2.size()); // a read-only accessor for m2cout << "m1: " << m1 << endl;cout << "m2: " << m2 << endl;cout << "Squared euclidean distance: " << (m1-m2).squaredNorm() << endl;cout << "Squared euclidean distance, using map: " << (m1-m2map).squaredNorm() << endl;m2map(3) = 7; // this will change m2, since they share the same arraycout << "Updated m2: " << m2 << endl;cout << "m2 coefficient 2, constant accessor: " << m2mapconst(2) << endl;//m2mapconst(2) = 5; // compile-time error: expression is not assignablecout << endl;}

執(zhí)行結(jié)果:

$ g++ -I /usr/local/include/eigen3 matrix_map2.cpp -o matrix_map2 $ $ ./matrix_map2 m1: -0.999984 -0.736924 0.511211 -0.0826997 0.0655345 m2: -0.562082 -0.905911 0.357729 0.358593 0.869386 Squared euclidean distance: 1.08479 Squared euclidean distance, using map: 1.08479 Updated m2: -0.562082 -0.905911 0.357729 7 0.869386 m2 coefficient 2, constant accessor: 0.357729

可以看到,對(duì)系數(shù)的訪問(wèn),使用括號(hào)運(yùn)算符(int index),矩陣的一些計(jì)算保持不變。
但這里有一個(gè)限制:你自己定義的函數(shù),使用Eigen的類(lèi)型時(shí),如果使用了Map,這和其對(duì)應(yīng)的密集矩陣類(lèi)Matrix可不一致了,因?yàn)樗鼈兪遣煌念?lèi)型Class。

使用placement new修改映射的數(shù)組

Map映射后得到的Matrix或者vector對(duì)象,也可以被修改。但這需要使用C++的placement new語(yǔ)法。

這里先對(duì)C++的Placemet new做一下說(shuō)明,這涉及到3種不同的new: new、operator new、placement new。

placement new是在用戶指定的內(nèi)存位置上構(gòu)建新的對(duì)象,那么這樣構(gòu)建時(shí),就不需要再額外分配內(nèi)存空間,只需要調(diào)用對(duì)象的構(gòu)造函數(shù)。就是這樣!因?yàn)閮?nèi)存和數(shù)據(jù)都已經(jīng)在那里了。其語(yǔ)法如此這樣:new(&p) constructor(......)。

下面看Eigen內(nèi)的一下Map相關(guān)的示例:

//matrix_map3.cpp #include <iostream> #include <Eigen/Dense>using namespace std; using namespace Eigen;int main() {int data[] = {1,2,3,4,5,6,7,8,9};Map<RowVectorXi> ov(data,9);cout << "Origin data: " << ov << endl; Map<RowVectorXi> v(data,4);cout << "The mapped vector v is: " << v << "\n";// placement new new (&v) Map<RowVectorXi>(data+4,5);cout << "Changed, Now v is: " << v << "\n";cout << "Again origin data: " << ov << endl; }

執(zhí)行結(jié)果:

$ g++ -I /usr/local/include/eigen3 matrix_map3.cpp -o matrix_map3 promote:eigen david$ ./matrix_map3 Origin data: 1 2 3 4 5 6 7 8 9 The mapped vector v is: 1 2 3 4 Changed, Now v is: 5 6 7 8 9 Again origin data: 1 2 3 4 5 6 7 8 9

使用這種placement new語(yǔ)法,可以聲明一個(gè)Map對(duì)象,而不用先分配內(nèi)存,也無(wú)需知道具體真實(shí)的數(shù)據(jù)。
比如:

//matrix_map4.cpp #include <iostream> #include <Eigen/Dense>using namespace std; using namespace Eigen;int n_matrices = 3; int data[] = {1,2,3,4,5,6,7,8,9};int* get_matrix_pointer(int i) {return data+3*i; }int main() {Map<Matrix3i> A(NULL); // // 此時(shí)對(duì)數(shù)據(jù)一無(wú)所知VectorXi b(n_matrices);for (int i = 0; i < n_matrices; i++){int * pp = get_matrix_pointer(i);cout << "point : " << pp << " : data " << *pp << endl;//new (&A) Map<Matrix3i>( pp );cout<< "Matrix A: "<< endl<<A<<endl;b(i) = A.trace();}cout<< "vector b : "<< endl<<b<<endl; }

執(zhí)行結(jié)果:

$ g++ -I /usr/local/include/eigen3 matrix_map4.cpp -o matrix_map4 $ ./matrix_map4 point : 0x106cb7880 : data 1 Matrix A: 1 4 7 2 5 8 3 6 9 point : 0x106cb788c : data 4 Matrix A: 4 7 0 5 8 0 6 9 0 point : 0x106cb7898 : data 7 Matrix A: 7 0 0 8 0 0 9 0 0 vector b : 15 127

總結(jié)

以上是生活随笔為你收集整理的Eigen入门之密集矩阵 7 - Map class:连接Eigen与C++的数据的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。