我正在使用Eigen廣泛使用並經常將Eigen::Matrix
對象與我自己設計的NSObject
子類(vMAT_Array
)映射的庫的代碼。與庫往往需要編組矩陣轉換成vMAT_Array
情況下,他們可以通過周圍,工作等有沒有辦法「強制」MatrixBase :: eval發生在模板函數參數上?
我有處理這個vMAT_cast
模板函數:
template <typename EigenObjectType>
vMAT_Array * vMAT_cast(EigenObjectType matrix)
{
return Map<EigenObjectType>(matrix).matA;
}
具有這種功能的問題是,它與Eigen的懶惰評估語義無法正確交互。就拿下面的單元測試代碼:
vMAT_Array * matM = vMAT_cast(VectorXd::LinSpaced(40, 1.0, 40.0).eval());
[matM reshape:vMAT_MakeSize(5, 8)];
Mat<double> M = matM;
Array<bool, Dynamic, Dynamic> sel = M.unaryExpr([](double elt) { return (int)elt % 3 == 0; }).cast<bool>();
vMAT_Array * vecN = vMAT_pick(matM, vMAT_cast(sel));
NSLog(@"%@", vecN.dump);
vMAT_Array * vecNv = vMAT_cast(VectorXd::LinSpaced(13, 3.0, 39.0).eval());
STAssertEqualObjects(vecN, vecNv, @"Logical indexing broken");
通知對大多數的參數vMAT_cast
明確.eval()
電話。這些是必要的,因爲模板函數嘗試(在編譯時),以擴展到使用代碼的徵懶惰表達式模板,從而產生這樣一個可愛的錯誤消息之一:
/Users/Shared/Source/vMAT/vMATTests/EigenTests.mm:25:35: note: in instantiation of member function 'Eigen::DenseBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >::LinSpaced' requested here
vMAT_Array * matM = vMAT_cast(VectorXd::LinSpaced(40, 1.0, 40.0));
^
In file included from /Users/Shared/Source/vMAT/vMATTests/EigenTests.mm:11:
In file included from /Users/Shared/Source/vMAT/vMAT/vMAT.h:51:
/Users/Shared/Source/vMAT/vMAT/vMAT_Array.h:122:82: error: no member named 'data' in 'Eigen::CwiseNullaryOp<Eigen::internal::linspaced_op<double, true>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >'
data:[NSMutableData dataWithBytes:matrix.data()
~~~~~~^
我懷疑有模板 - 這會「迫使」MatrixBase::eval
發生,但我缺乏這方面的知識。任何人都可以啓發我嗎?
啊,我*想*我看到表達式是如何工作的......它是在編譯時計算的,如果'IsGLCompatible'是'false',那麼在調用函數之前有一個專門化「修正」參數。我沒有看到我可以使用'Ref'模板類。 –
假設你只能映射順序存儲的列主矩陣,然後你聲明'vMAT_cast'函數爲'vMAT_cast(參考>矩陣);'任何不與' MatrixXd'將被評估。如果'vMAT_Array'支持跨度,則將其聲明爲:'vMAT_cast(Ref matrix)'。 –
ggael
謝謝澄清...我的困難是我不知道什麼類型的矩陣庫用戶可能想投。我的** Objective-C **庫試圖使用'vMAT_Array *'作爲「ref」類型,您可以輕鬆地將它傳遞給函數,方法等等。所以,我可能需要挖掘源代碼** Eigen **'Ref'在某個點上的東西?但是因爲我可以(大部分)理解你所描述的第一種方法是如何工作的,所以我想我會先嚐試。 (目前我仍在向所有地方噴灑'.eval()'......) –