2017-04-25 68 views
0

給定一個數據矩陣X,我想計算任意兩行X之間的成對距離矩陣。我有下面的代碼,它來自略微調整代碼here爲什麼我的Rcpp代碼會給出意想不到的所有整數值輸出?

#include <Rcpp.h> 
#include <cmath> 
#include <algorithm> 

using namespace Rcpp; 
// generic function for l1_distance 
template <typename InputIterator1, typename InputIterator2> 
inline double l1_distance(InputIterator1 begin1, InputIterator1 end1, 
          InputIterator2 begin2) { 
    double rval = 0; 
    InputIterator1 it1 = begin1; 
    InputIterator2 it2 = begin2; 
    while (it1 != end1) { 
     double d1 = *it1++; 
     double d2 = *it2++; 
     rval += abs(d1 - d2); 
    } 
    return rval; 
} 

// [[Rcpp::export]] 
NumericMatrix rcpp_l1_distance(NumericMatrix mat) { 

    // allocate the matrix we will return 
    NumericMatrix rmat(mat.nrow(), mat.nrow()); 
    for (int i = 0; i < rmat.nrow(); i++) { 
     for (int j = 0; j < i; j++) { 
     NumericMatrix::Row row1 = mat.row(i); 
     NumericMatrix::Row row2 = mat.row(j); 
     double d = l1_distance(row1.begin(), row1.end(), row2.begin()); 
     rmat(i,j) = d; 
     rmat(j,i) = d; 
     } 
    } 
    return rmat; 
} 

問題是此代碼返回所有整數值的矩陣。整數值似乎與我想要的距離值正相關,這使得它更容易混淆。我還計算了一個成對的l2距離矩陣和成對歸一化的l1距離(兩行之間的l1距離除以它們的l1範數的總和)矩陣,並且它們都按預期行事。

有人可以告訴我我犯了哪個錯誤嗎?

您可以執行以下操作來獲得怪異的結果

library(Rcpp) 
sourceCpp("distance.cpp") #the file containing the cpp code above 
X = matrix(rnorm(16), 4, 4) 
rcpp_l1_distance(X) 

提前感謝!

+1

正如一個側面說明,你也可以使用'stats :: dist'函數與'method =「manhattan」'。 – NoBackingDown

+0

只要確保。我可以在那裏的C++腳本中做到這一點? – user2804929

回答

2

編譯代碼給了我這些警告:

> Rcpp::sourceCpp('Desktop/mat.cpp') 
mat.cpp:16:15: warning: using integer absolute value function 'abs' when argument is of floating point type [-Wabsolute-value] 
     rval += abs(d1 - d2); 
      ^
mat.cpp:16:15: note: use function 'std::abs' instead 
     rval += abs(d1 - d2); 
       ^~~ 
       std::abs 
mat.cpp:16:15: warning: using integer absolute value function 'abs' when argument is of floating point type [-Wabsolute-value] 
     rval += abs(d1 - d2); 
      ^
mat.cpp:30:18: note: in instantiation of function template specialization 'l1_distance<Rcpp::MatrixRow<14>::iterator, Rcpp::MatrixRow<14>::iterator>' requested here 
     double d = l1_distance(row1.begin(), row1.end(), row2.begin()); 
       ^
mat.cpp:16:15: note: use function 'std::abs' instead 
     rval += abs(d1 - d2); 
       ^~~ 
       std::abs 
2 warnings generated. 

...暗示abs是整數,看到this help page,您可以用fabs代替,或std::abs,或者您可以使用糖的operator-abssum

#include <Rcpp.h> 

using namespace Rcpp; 

// [[Rcpp::export]] 
NumericMatrix rcpp_l1_distance(NumericMatrix mat) { 

    // allocate the matrix we will return 
    NumericMatrix rmat(mat.nrow(), mat.nrow()); 
    for (int i = 0; i < rmat.nrow(); i++) { 
    NumericMatrix::Row row1 = mat.row(i); 

    for (int j = 0; j < i; j++) { 
     rmat(j,i) = rmat(i,j) = sum(abs(row1 - mat.row(j))) ; 
    } 
    } 
    return rmat; 
} 
+0

作爲一般規則,您希望啓用來自編譯器的警告生成,這有助於捕獲像這樣的問題。 –

+0

非常感謝你們!我必須爲編譯器啓用警告。 – user2804929

相關問題