Note that there are some explanatory texts on larger screens.

plurals
  1. POfirst derivative of multivariate normal/gaussian with rcpp and RcppArmadillo
    primarykey
    data
    text
    <p>I am trying to implement the first derivative of the multivariate normal distribution in R building on the <code>rcpp</code> implementation of the multivariate normal distribution posted <a href="https://stackoverflow.com/questions/17617618/dmvnorm-mvn-density-rcpparmadillo-implementation-slower-than-r-package-includi">here</a> and <a href="http://gallery.rcpp.org/articles/dmvnorm_arma/" rel="nofollow noreferrer">here</a>.</p> <p>Here is a quick R implementation</p> <pre><code>mvnormDeriv = function(..., mu=rep(0,length(list(...))), sigma=diag(length(list(...)))) { if(sd(laply(list(...),length))!=0) stop("The vectors not same length.") fn = function(x) -1 * c((1/sqrt(det(2*pi*sigma))) * exp(-0.5*t(x-mu)%*%solve(sigma)%*%(x-mu))) * solve(sigma,(x-mu)) out = t(apply(cbind(...),1,fn)) colnames(out) = c('x', 'y') return(out[,1]) } </code></pre> <p>and some test data with benchmark:</p> <pre><code>set.seed(123456789) sigma = rWishart(1, 2, diag(2)) means = rnorm(2) X = rmvnorm(10000, means, sigma[,,1]) x1 = X[,1] x2 = X[,2] benchmark(mvnormDeriv(x1,x2,mu=means,sigma=sigma), order="relative", replications=5)[,1:4] </code></pre> <p>The formula can be found in the matrix cookbook (2012), formula 346.</p> <p>I failed to modify the <code>rcpp</code> implementation of the multivariate normal from <a href="http://gallery.rcpp.org/articles/dmvnorm_arma/" rel="nofollow noreferrer">here</a>. Here is some code, which I used to try</p> <pre><code>// [[Rcpp::export]] arma::vec dmvnormDeriv_arma(arma::mat x, SEXP mu_sexp, arma::mat sigma, bool log = false) { // create Rcpp vector and matrix from SEXP arguments Rcpp::NumericVector mu_rcpp(mu_sexp); // create views for arma objects(reuses memory and avoids extra copy) arma::vec mu_vec(mu_rcpp.begin(), mu_rcpp.size(), false); arma::rowvec mu(mu_rcpp.begin(), mu_rcpp.size(), false); // return(mu_vec); arma::vec distval = Mahalanobis(x, mu, sigma); double logdet = sum(arma::log(arma::eig_sym(sigma))); double log2pi = std::log(2.0 * M_PI); arma::vec val = exp(-( (x.n_cols * log2pi + logdet + distval)/2)); // x.each_row() -= mu; // arma::vec val2 = solve(sigma, x.row(1)); // arma::vec retval = -1 * val(1) * solve(sigma, x.row(1)-mu_vec); return(val); } </code></pre> <p>This is not complete, of course. Any ideas how I can implement the <code>* solve(sigma,(x-mu))</code> part in <code>rcpp</code> or with <code>Armadillo</code>? I have problems handling the different variables types and running the solve for each row of x.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload