Reputation: 268
I am converting some R code to Rcpp code and need to calculate the likelihood for a vector of observations given a vector of means and vector of standard deviations. If I assume the means are 0 and the standard deviations 1, I can write this function (running this requires the 'inline' and 'Rcpp' packages to be loaded),
dtest1 = cxxfunction(signature( x = "numeric"),
'Rcpp::NumericVector xx(x);
return::wrap(dnorm(xx, 0.0, 1.0));',
plugin='Rcpp')
and the result is as expected.
> dtest1(1:3)
[1] 0.241970725 0.053990967 0.004431848
However, if I try to make a function
dtest2 = cxxfunction(signature( x = "numeric", y="numeric", z="numeric" ),
'Rcpp::NumericVector xx(x);
Rcpp::NumericVector yy(y);
Rcpp::NumericVector zz(z);
return::wrap(dnorm(xx, yy, zz));',
plugin='Rcpp')
which would allow me to pass in different means and standard deviations results in an error, shown below. Is there a way to make the function I am trying to make, or I do need to program the normal density manually?
Error
Error in compileCode(f, code, language = language, verbose = verbose) :
Compilation ERROR, function(s)/method(s) not created! file31c82bff9d7c.cpp: In function ‘SEXPREC* file31c82bff9d7c(SEXP, SEXP, SEXP)’:
file31c82bff9d7c.cpp:33:53: error: no matching function for call to
‘dnorm4(Rcpp::NumericVector&, Rcpp::NumericVector&, Rcpp::NumericVector&)’
file31c82bff9d7c.cpp:33:53: note: candidates are:
/home/chris/R/x86_64-pc-linux-gnu-library/3.0/Rcpp/include/Rcpp/stats/norm.h:106:1:
note: template<int RTYPE, bool NA, class T> Rcpp::stats::D0<RTYPE, NA, T> Rcpp::dnorm4(const Rcpp::VectorBase<RTYPE, NA, VECTOR>&, bool)
/home/chris/R/x86_64-pc-linux-gnu-library/3.0/Rcpp/include/Rcpp/stats/norm.h:107:1:
note: template<int RTYPE, bool NA, class T> Rcpp::stats::D1<RTYPE, NA, T> Rcpp::dnorm4(const Rcpp::VectorBase<RTYPE, NA, VECTOR>&, double, bool)
/home/chris/R/x86_64-pc-linux-gnu-library/3.0/Rcpp/include/Rcpp/stats/norm.h:108:1:
note: template<int RTYPE, bool NA, class T> Rcpp::stats::D2<RTYPE, NA, T> Rcpp::dnorm4(const Rcpp::VectorBase<RTYPE, NA,
In addition: Warning message:
running command '/usr/lib/R/bin/R CMD SHLIB file31c82bff9d7c.cpp 2> file31c82bff9d7c.cpp.err.txt' had status 1
Upvotes: 3
Views: 2589
Reputation: 17642
The sugar dnorm
is only vectorized in terms of the first argument.
To simplify (it is slightly more involved, but we don't need to concern ourselves with this yet here), the call
dnorm(xx, 0.0, 1.0)
uses the overload
NumericVector dnorm( NumericVector, double, double )
And the second call tries to use something like
NumericVector dnorm( NumericVector, NumericVector, NumericVector )
which is not implemented. We could implement it, it would have to go high enough in our priority list.
In the meantime, it is easy enough to write a small wrapper, like (this does not handle argument lengths, etc ...) :
NumericVector my_dnorm( NumericVector x, NumericVector means, NumericVector sds){
int n = x.size() ;
NumericVector res(n) ;
for( int i=0; i<n; i++) res[i] = R::dnorm( x[i], means[i], sds[i] ) ;
return res ;
}
Upvotes: 7