2016-10-13 3 views
2

От R, я пытаюсь запустить sourceCpp на данный файл:Использование dnorm с RcppArmadillo

#include <RcppArmadillo.h> 
// [[Rcpp::depends(RcppArmadillo)]] 

using namespace arma; 
using namespace Rcpp; 

// [[Rcpp::export]] 
vec dnormLog(vec x, vec means, vec sds) { 
    int n = x.size(); 
    vec res(n); 
    for(int i = 0; i < n; i++) { 
     res[i] = log(dnorm(x[i], means[i], sds[i])); 
    } 
return res; 
} 

См this answer, чтобы увидеть, где я получил функцию от. Это бросает ошибку:

no matching function for call to 'dnorm4'

Каких точная ошибка, я надеялся предотвратить с помощью цикла, так как ссылки ответа упоминает, что dnorm только векторная относительно первого аргумента. Я боюсь, что ответ очевиден, но я попытался добавить R:: до dnorm, попробовал использовать NumericVector вместо vec, не используя log() спереди. Не повезло. Однако, добавление R:: перед тем dnorm действительно производит отдельную ошибку:

too few arguments to function call, expected 4, have 3; did you mean '::dnorm4'? 

Который является не фиксируется путем замены dnormR::dnorm4 выше.

ответ

6

Есть два хороших понятливый моментов здесь:

  1. Обратите внимание на пространство имен. Если вы сомневаетесь, не ходите глобально.
  2. Проверьте заголовки на предмет фактических определений. Вы пропустили четвертый аргумент в сканере версии R::dnorm().

Вот исправленный вариант, в комплект входит второй вариант, который вы можете найти интересные:

#include <RcppArmadillo.h> 
// [[Rcpp::depends(RcppArmadillo)]] 

// [[Rcpp::export]] 
arma::vec dnormLog(arma::vec x, arma::vec means, arma::vec sds) { 
    int n = x.size(); 
    arma::vec res(n); 
    for(int i = 0; i < n; i++) { 
    res[i] = std::log(R::dnorm(x[i], means[i], sds[i], FALSE)); 
    } 
    return res; 
} 

// [[Rcpp::export]] 
arma::vec dnormLog2(arma::vec x, arma::vec means, arma::vec sds) { 
    int n = x.size(); 
    arma::vec res(n); 
    for(int i = 0; i < n; i++) { 
    res[i] = R::dnorm(x[i], means[i], sds[i], TRUE); 
    } 
    return res; 
} 


/*** R 
dnormLog(c(0.1,0.2,0.3), rep(0.0, 3), rep(1.0, 3)) 
dnormLog2(c(0.1,0.2,0.3), rep(0.0, 3), rep(1.0, 3)) 
*/ 

Когда мы источник этого, оба возвращают один и тот же результат , потому что R API позволяет задать для логарифмов принимается.

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

R> dnormLog(c(0.1,0.2,0.3), rep(0.0, 3), rep(1.0, 3)) 
      [,1] 
[1,] -0.923939 
[2,] -0.938939 
[3,] -0.963939 

R> dnormLog2(c(0.1,0.2,0.3), rep(0.0, 3), rep(1.0, 3)) 
      [,1] 
[1,] -0.923939 
[2,] -0.938939 
[3,] -0.963939 
R> 
+1

Мертвые с замечанием об пространствах имен. 'using namespace [...]' вызывает намного больше проблем, чем решает мой опыт. – nrussell

+0

А теперь я вижу. Для проблемы с 4-м аргументом я сначала пытался передать 'log = TRUE', но я должен был бы передать TRUE. Теперь я помню, как осложнения, связанные с передачей именованных аргументов в документации. Спасибо за очень информативный ответ. – Jason