2017-02-15 148 views
0

請注意,此錯誤來自更大的上下文,我完全無法在此完全報告。Rcpp中的意外行爲

我在文件fun.cpp

#include <RcppArmadilloExtensions/sample.h> 

using namespace Rcpp; 

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

arma::vec colMeans(arma::mat data){ 

    int n_0 = data.n_rows; 

    arma::vec xbar(data.n_cols); 
    for(int i = 0; i < data.n_rows; i++){ 
     for(int j = 0; j < data.n_cols; j++){ 
     xbar[j] += data(i,j) /n_0; 
     } 
    } 

    return xbar; 
} 

// [[Rcpp::export]] 
List PosteriorNIW(arma::mat data, arma::vec mu0, double lambda0, 
       double df0, arma::mat V){ 

    // Compute posterior 
    int n = data.n_rows; 

    arma::vec xbar = colMeans(data); 

    double lambdan = lambda0 + n; 

    arma::vec mun = (lambda0 * mu0 + n * xbar)/lambdan; 

    arma::mat S; 
    S.zeros(data.n_cols, data.n_cols); 
    for(int i = 0; i < n; i++){ 
     S += (arma::conv_to<arma::vec>::from(data.row(i)) - xbar) * arma::trans(arma::conv_to<arma::vec>::from(data.row(i)) - xbar); 
    } 

    arma::mat Vn = V + S + ((lambda0*n)/(lambda0 + n)) * (xbar - mu0) * arma::trans(xbar - mu0); 

    return List::create(_["mun"] = mun, 
        _["Vn"] = Vn, 
        _["lambdan"] = lambdan); 
} 

以下功能立即致電:

library(Rcpp); library(RcppArmadillo) 
mu0 <- c(3,3) 
V0 <- matrix(c(2.5,0.0,0.0,2.5), nrow = 2) 
sourceCpp("fun.cpp") 

data <- cbind(rep(5,15),rep(0,15)) 
PosteriorNIW(data, mu0, 1, 1, V0) 

給出了預期的結果。

$mun 
    [,1] 
[1,] 4.8750 
[2,] 0.1875 

$Vn 
    [,1] [,2] 
[1,] 6.250 -5.6250 
[2,] -5.625 10.9375 

$lambdan 
[1] 16 

現在,如果我添加到文件fun.cpp以下功能(再次,這些都是從一個更大的背景下采取所以也懶得試圖瞭解,但只是將它們粘貼)奇怪的事情發生了:

// [[Rcpp::export]] 
NumericMatrix myFun(arma::mat t_dish, arma::cube data){ 
    int l = 0; 
    for(int j = 0; j < data.n_rows; j++){ 
     l++; 
    } 
    NumericMatrix Dk(l, 2); 
    return Dk; 
} 

// [[Rcpp::export]] 
int myFun2(arma::cube n_cust){ 

    arma::mat temp = n_cust.subcube(arma::span(0), arma::span(), arma::span()); 
    int i; 
    for(i = 0; i < n_cust.n_cols; i++){ 
     arma::rowvec temp2 = temp.row(i); 
    } 

    return i + 1; 
} 

// [[Rcpp::export]] 
arma::vec myFun3(arma::mat k_tables){ 
    arma::vec temp(k_tables.n_cols * k_tables.n_rows); 
    int l = 0; 
    if(!R_IsNA(k_tables(0,0))){ 
     l++; 
    } 

    arma::vec temp2(l); 
    arma::vec tmp3 = sort(temp2); 
    return tmp3; 
} 

double myFun4(arma::vec x, double nu, arma::vec mu, arma::mat Sigma){ 
    arma::vec product = (arma::trans(x - mu) * arma::inv(Sigma) * (x - mu)); 
    double num = pow(1 + (1/nu) * product[0], - (nu + 2)/2); 
    double den = pow(sqrt(M_PI * nu),2) * sqrt(arma::det(Sigma)); 
    return num/den; 
} 

bool myFun5(NumericVector X, double z) { 
    return std::find(X.begin(), X.end(), z)!=X.end(); 
} 

調用PosteriorNIW(data, mu0, 1, 1, V0)重複開始每次都會給出不同的結果。請注意,函數中沒有隨機性,顯然這些函數沒有影響,因爲它們在原始函數中未被調用。

我試過不同的機器,以確保它不是我的編譯器的問題,但錯誤不斷髮生。

我知道,刪除這些功能(即使只是其中之一)可以解決這個問題,但顯然,當我使用更多功能時,這不是一個可行的解決方案。

我想知道其他用戶是否能夠複製此行爲,如果是,如果有修復它。

預先感謝您

編輯:

R的版本是3.3.2和Rtools爲3.4。 Rcpp和RcppArmadillo都是最新的

+1

請使用縮進。上面的格式是* abysmal *,並且很難讀取您的代碼。 – nrussell

+0

對不起,它在粘貼時刪除了縮進。現在應該更容易閱讀 – adaien

+1

您不支付空白。許多人使用四個,一些可憐的人認爲兩個更好。其中一個基本上是不可讀的。如果你想得到我們的免費幫助,請不要讓我們更難。 –

回答

1

您沒有在您的colMeans函數中調零xbar。如果我不這樣做:

arma::vec colMeans(arma::mat data){ 

    int n_0 = data.n_rows; 

    arma::vec xbar; 
    xbar.zeros(data.n_cols); 
    for(int i = 0; i < data.n_rows; i++){ 
     for(int j = 0; j < data.n_cols; j++){ 
     xbar[j] += data(i,j) /n_0; 
     } 
    } 

    return xbar; 
} 

我得到這個每次:

> PosteriorNIW(data, mu0, 1, 1.1, V0) 
$mun 
     [,1] 
[1,] 4.8750 
[2,] 0.1875 

$Vn 
     [,1] [,2] 
[1,] 6.250 -5.6250 
[2,] -5.625 10.9375 

$lambdan 
[1] 16 

即使我添加的代碼的額外塊。

我不知道這些向量是否被記錄爲由它們的構造函數初始化爲0(在這種情況下,這可能是一個錯誤)或不是,在這種情況下它的bug!

+0

非常好,非常感謝! – adaien

+0

我在這些情況下的調試技巧是打印出計算出來的東西,找出事情發生的地方。這導致了我的「colMeans」函數,然後我發現了非零矢量。 – Spacedman

+0

我通常會這樣做,但是當我試圖在'PosteriorNIW'函數中打印'n'時,只需添加打印功能就可以工作並刪除錯誤。乾杯 – adaien