I need to evaluate a large number of binomial likelihoods very quickly. Therefore, I am thinking of implementing this in Rcpp. One way to do it is the following:
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector eval_likelihood(arma::vec Yi,
                              arma::vec Ni,
                              arma::vec prob){
  // length of vector
  int N = prob.n_rows;
  // storage for evaluated log likelihoods
  NumericVector eval(N);
  for(int ii = 0; ii < N; ii++){
  int y = Yi(ii); // no. of successes
  int n = Ni(ii); // no. of trials
  double p = prob(ii); // success probability
  eval(ii) = R::dbinom(y,n,p,true); // argument 4 is set to true to return log-likelihood
  }
  return eval;
}
which returns equivalent log-likelihoods as dbinom() in R:
Rcpp::sourceCpp("dbinom.cpp") #source Rcpp script
# fake data
Yi    = 1:999  
Ni    = 2:1000
probs = runif(999)
evalR    = dbinom(Yi, Ni, probs, log = T) # vectorized solution in R
evalRcpp = eval_likelihood(Yi, Ni, probs) # my Rcpp solution
identical(evalR,evalRcpp)
[1] TRUE
That is, in general, a nice outcome. However, the vectorized R solution is on average slightly faster than my naive Rcpp solution:
microbenchmark::microbenchmark(R    = dbinom(Yi, Ni, probs, log = T),
                               Rcpp = eval_likelihood(Yi, Ni, probs))
Unit: microseconds
 expr     min      lq     mean   median       uq      max neval cld
    R 181.753 182.181 188.7497 182.6090 189.4515  286.100   100   a
 Rcpp 178.760 179.615 197.5721 179.8285 184.7470 1397.144   100   a
Does anyone have some guidance towards a faster evaluation of binomial log-likelihoods? Could be either faster code or some hack from probability theory. Thanks!