2015-07-13 30 views
0

我試圖返回兩個向量的內積在.C中與R.此後,我希望函數返回true,如果內積等於零,否則返回false 。 我寫了一個小的.cpp函數來計算正確的內部產品。 當我有長度的矢量2 例如< - C(5,-5) b < - C(5,5)使用R和.C返回點積

此返回0作爲結果和真作爲結果等於零。

然而,當我增加在R調用代碼向量的長度 例如< - C(5,-5,4) b < - C(5,5,4)

它返回16作爲結果是很好的,但它返回的結果不等於零,這是不正確的 。

任何人都可以幫助理解我在這裏做錯了嗎?

該代碼是下面的.C

#include <R.h> 
extern "C" { 
    void test(int * x1, int * x2, int * len, int * result, bool * tf) 
    { 
     int n = *len; 
     *result = 0; 
     for (int i = 0; i < n; i++) 
     { 
      *result = *result + x1[i] * x2[i]; 
      if (*result == 0) 
      { 
       *tf = TRUE; 
      } 
     } 
    } 
} 

我已經改變這對代碼

#include <R.h> 

extern "C" { 

    void test (int * x1, int * x2, int * len, int * result, int * tf) 
// void test (int * x1, int * x2, int * result) 
    { 
    int n = *len ; 
     *result = 0; 
     for (int i = 0; i < n; i++) 
     *result += x1[i] * x2[i]; 
     *tf = *result == 0; 
    } 
    } 

,當我用R調用此,如下

a <- c(-5,5,4) 
b <- c(5,5,3) 
len <- length(a) 
c <- 0 
ans <- FALSE 

.C("test", x1 = as.integer(a), x2 = as.integer(b), 
    len = as.integer(length(a)), 
    result = as.integer(c), 
    tf = as.logical(ans)) 

的輸出爲

$x1 
[1] -5 5 4 

$x2 
[1] 5 5 3 

$len 
[1] 3 

$result 
[1] 12 

$tf 
[1] TRUE 

由於結果不是0 tf應該是FALSE,它是當矢量長度爲1或2時。只有當我增加到3或更長時,這是否會發生。任何人都可以幫忙嗎?

+0

您沒有將* tf設置爲FALSE。順便說一句,我沒有看到tf在任何地方定義。 – AndreiM

+1

'tf'是什麼?它沒有在任何地方聲明。我假定它的函數的返回值(也沒有顯示),如果是這樣的話,以前的評論適用。另外,我認爲你想在for循環完成後檢查(* result == 0)**,而不是在執行期間。 – user2867342

+0

@ user2867342是的,它被傳遞給函數。 –

回答

1

您的代碼是越野車。這裏是固定的版本:

#include <R.h> 
extern "C" { 
    void isOrthn (int * x1, int * x2, int * len, int * result, bool * tf) 
    { 
     int n = *len ; 
     *result = 0; 
     for (int i = 0; i < n; i++) 
     *result += x1[i] * x2[i]; 
     *tf = *result == 0; 
    } 
} 

基本上,你可以離開,而無需初始化tf。通過在循環外部移動測試,它更簡單,更清晰,並且清楚地看到* tf的值在功能上取決於結果爲0.

+0

可能是你編組R的參數的方式。上面的C代碼是正確的。看看你最後一個參數(bool)的類型可能是R的問題。 –

+0

謝謝。當我使用R來調用這個函數時,它不會爲tf返回正確的答案,除非矢量的長度只有2?我會看看最後一個參數的類型。 – oldtimetrad

+0

我在編輯中添加了R代碼,與您的修改相同,它仍然沒有像我期望的那樣返回? – oldtimetrad

2

簡述:

  • 不要使用.C(),它的使用在所有的新代碼氣餒(在R-devel的CF討論在過去的幾年裏)。

  • 您的代碼,因爲它不計算完整的內部產品之前測試中的邏輯錯誤:完成循環

下面是我怎麼會在RcppArmadillo寫:

#include <RcppArmadillo.h> 

// [[Rcpp::depends(RcppArmadillo)]] 

// [[Rcpp::export]] 
bool checkInner(const arma::vec a, const arma::vec b) { 
    double ip = arma::as_scalar(a.t() * b); 
    return ip == 0.0; 
} 

/*** R 
checkInner(c(1,2), c(-2,1)) 
checkInner(1:3, 2:4) 
*/ 

我們只需要sourceCpp(...)這個文件,它被編譯,鏈接,加載並且底部的R代碼也運行:

R> sourceCpp("/tmp/inner.cpp") 

R> checkInner(c(1,2), c(-2,1)) 
[1] TRUE 

R> checkInner(1:3, 2:4) 
[1] FALSE 
R>