2015-03-03 130 views
1

在MATLAB中,您可以通過閾值一個矩陣如下創建一個二進制矩陣B:有沒有一種方法來存儲閾值操作輸出特徵(C++)?

B = A > threshold 

哪裏threshold一定的價值。在Eigen for C++中,我能夠看到類似的結果,但卻無法分配輸出。也就是說,給定

MatrixXd M = 
0 1 2 
0 1 2 
0 1 2 

(我知道這不是正確的初始化,但對於這個問題的緣故,去用它)

cout << (M < 1) 

產生

1 0 0 
1 0 0 
1 0 0 

MatrixXd N = M < 1; 

and

M = M < 1; 

都給出了構建錯誤。

有人可以請解釋正確的方法來保存這個閾值的二進制輸出到一個變量嗎?

回答

4

operator<僅被定義在陣列的世界,所以你必須使用.array()看你MatrixXdArrayXXd(沒有複製在這裏),然後將結果是布爾的陣列,所以如果你想雙,那麼你必須明確地施展:

MatrixXd M(3,3); 
M << 0, 1, 2, 
    0, 1, 2, 
    0, 1, 2; 
MatrixXb Rb = (M.array() < 0.5);     // result as a matrix of bool 
MatrixXd Rd = (M.array() < 0.5).cast<double>(); // result as a matrix of double 
+1

有一點需要指出的是我不相信MatrixXb有一個gobal typedef,所以有必要自己做:typedef Matrix MatrixXb; – marcman 2015-03-03 16:05:27

1

我無法使用std::cout << (M < 1)重現您的結果,也無法在任何地方找到此文檔。

您可以通過使用unaryExpr成員函數將一元函數應用於每個元素,從現有元素創建一個新矩陣。使用C++ 11 lambda表達式,這變得非常簡單。

#include <iostream> 
#include <Eigen/Dense> 

int 
main() 
{ 
    Eigen::MatrixXd m1(4, 3); 
    m1.setRandom(); 
    Eigen::MatrixXd m2 = m1.unaryExpr([](double d){ return d < 0.5; }); 
    std::cout << m1 << "\n\n" << m2 << "\n"; 
} 

可能的輸出:

0.680375 0.823295 -0.444451 
-0.211234 -0.604897 0.10794 
    0.566198 -0.329554 -0.0452059 
    0.59688 0.536459 0.257742 

0 0 1 
1 1 1 
0 1 1 
0 0 1 

不,我知道爲什麼你想有存儲在一個真正的矩陣布爾運算的結果,但你肯定能做到這一點。此外,通常應避免將矩陣表達式的結果顯式轉換爲MatrixXd(或任何其他顯式類型),因爲每次執行此操作時,都會在Eigen強大的表達式模板鏈中設置一個剪切。在C++ 11中,除非您真的需要急切的評估/類型轉換,否則請使用auto

+0

你知道嗎?我想這可能是因爲我在使用ArrayXXd。如果您將MatrixXd轉換爲ArrayXXd,您應該會看到我的cout結果。至於存儲在一個真正的矩陣,我想它可以是一個布爾值。最後一部分:我不認爲我明白你對顯式轉換的含義。你介意闡述嗎? – marcman 2015-03-03 06:17:43

+1

@marcman在Eigen中,'MatrixXd + MatrixXd'的結果類型不是*'MatrixXd',而是一些可以隱式轉換爲'MatrixXd'的特殊表達式模板。但這種轉換是懶惰地完成的。這樣做的好處是,如果您在另一個表達式中使用前一個表達式的結果,而不是在矩陣元素上循環兩次,Eigen內核就能夠將這些操作融合到一個更高效的緩存循環中。 – 5gon12eder 2015-03-03 18:43:08

相關問題