2017-01-31 18 views
6

Konwertuję funkcję R na Rcpp, gdzie użyłem funkcji R rowSums, która wydaje się być nieprawidłowym wyrażeniem cukru w ​​Rcpp. Znalazłem kod dla wersji Rcpp rowSums here. Ale jestem corazJak obliczyć rowSums w rcpp

error: use of undeclared identifier

kiedy używam rowSumsC() w moim głównej funkcji RCPP.

Czy łatwo naprawić?

Edycja: Kod

cppFunction(
    "NumericMatrix Expcpp(NumericVector x, NumericMatrix w, 
    NumericVector mu, NumericVector var, NumericVector prob, int k) { 
    for (int i=1; i<k; ++i){ 
    w(_,i) = prob[i] * dnorm(x,mu[i], sqrt(var[i])); 
    } 
    w = w/rowSums(w) 
    return w; 
}") 
+1

Utwórz powtarzalne przykładu (na przykład kod pocztowy i połączenia). Istnieje również odpowiednik cukru Rcpp dla 'rowSums'. Zostało dodane w Rcpp 0.12.8 – coatless

+0

Przesłałem kod. Naprawdę nie mogę tego nazwać, ponieważ nie można go zdefiniować z powodu braku identyfikacji identyfikatorów rowsSums. Jaka jest nazwa odpowiednika rcpp dla rowSums i czy muszę zrobić coś ekstra, aby to nazwać? Jestem naprawdę nowy w rcpp. –

Odpowiedz

6

Rcpp officially added rowSum support in 0.12.8. W związku z tym nie ma potrzeby korzystania z funkcji opracowanej przez Hadleya w Advanced R.

Powiedziawszy to, jest kilka problemów z kodem.


RCPP obecnie robi nie Wsparcie Matrix do Vector lub Matrix do Matrix obliczenia. (Wsparcie dla późniejszego może być dodane za #583, ale w razie potrzeby należy rozważyć użycie RcppArmadillo lub RcppEigen). Dlatego poniżej linii jest problematyczne:

w = w/rowSums(w) 

Aby rozwiązać ten problem, najpierw obliczenie rowSums i ujednolicenia matrycy za pomocą tradycyjnego for pętli. Uwaga: pętli w C++ jest bardzo szybki w przeciwieństwie R.

NumericVector summed_by_row = rowSums(w); 

for (int i = 0; i < k; ++i) { 
    w(_,i) = w(_,i)/summed_by_row[i]; 
} 

Następny, C++ indeksy rozpoczynają się 0 nie 1. Dlatego dodaje się do pętli jest problematyczne:

for (int i=1; i<k; ++i) 

Rozwiązaniem:

for (int i=0; i<k; ++i) 

Wreszcie, parametry funkcji można zmniejszyć jak niektóre wartości nie mają znaczenia lub są zastępowane .

Deklaracja funkcja przechodzi od:

NumericMatrix Expcpp(NumericVector x, NumericMatrix w, 
    NumericVector mu, NumericVector var, NumericVector prob, int k) 

Do:

NumericMatrix Expcpp(NumericVector x, NumericVector mu, NumericVector var, NumericVector prob) { 

    int n = x.size(); 
    int k = mu.size(); 
    NumericMatrix w = no_init(n,k); 

    ..... 

Umieszczenie wszystkich powyższych informacji zwrotnej razem, otrzymujemy żądaną funkcję.

Rcpp::cppFunction(
    'NumericMatrix Expcpp(NumericVector x, NumericVector mu, NumericVector var, NumericVector prob) { 

    int n = x.size(); 
    int k = mu.size(); 

    NumericMatrix w = no_init(n,k); 

    for (int i = 0; i < k; ++i) { // C++ indices start at 0 
    w(_,i) = prob[i] * dnorm(x, mu[i], sqrt(var[i])); 
    } 

    Rcpp::Rcout << "Before: " << std::endl << w << std::endl; 

    NumericVector summed_by_row = rowSums(w); 

    Rcpp::Rcout << "rowSum: " << summed_by_row << std::endl; 

    // normalize by column to mimic R 
    for (int i = 0; i < k; ++i) { 
    w(_,i) = w(_,i)/summed_by_row[i]; 
    } 

    Rcpp::Rcout << "After: " << std::endl << w << std::endl; 

    return w; 
    }') 

set.seed(51231) 
# Test values 
n <- 2 
x <- seq_len(n) 
mu <- x 
var <- x 
prob <- runif(n) 

mat <- Expcpp(x, mu, var, prob) 

wyjściowy

Before: 
0.0470993 0.125384 
0.0285671 0.160996 

rowSum: 0.172483 0.189563 
After: 
0.273066 0.661436 
0.165623 0.849300