If you're open to switching from C to C++, you get added layer of Rcpp for free. Here is an example from the page of the (still rather incomple) RcppExample package:
#include <RcppClassic.h>
#include <cmath>
RcppExport SEXP newRcppVectorExample(SEXP vector) {
BEGIN_RCPP
Rcpp::NumericVector orig(vector); // keep a copy
Rcpp::NumericVector vec(orig.size()); // create vector same size
// we could query size via
// int n = vec.size();
// and loop over the vector, but using the STL is so much nicer
// so we use a STL transform() algorithm on each element
std::transform(orig.begin(), orig.end(), vec.begin(), ::sqrt);
return Rcpp::List::create(Rcpp::Named( "result" ) = vec,
Rcpp::Named( "original" ) = orig) ;
END_RCPP
}
As you see, no explicit memory allocation, freeing, PROTECT/UNPROTECT
etc, and you get a first class R list object back.
There are lots more examples, included in other SO questions such as this one.
Edit: And you didn't really say what you paths would do, but as a simple illustration, here is C++ code using the Rcpp additions cumsum()
and rpois()
which behave just like they do in R:
R> library(inline)
R>
R> fun <- cxxfunction(signature(ns="integer", lambdas="numeric"),
+ plugin="Rcpp",
+ body='
+ int n = Rcpp::as<int>(ns);
+ double lambda = Rcpp::as<double>(lambdas);
+
+ Rcpp::RNGScope tmp; // make sure RNG behaves
+
+ Rcpp::NumericVector vec = cumsum( rpois( n, lambda ) );
+
+ return vec;
+ ')
R> set.seed(42)
R> fun(3, 0.3)
[1] 1 2 2
R> fun(4, 0.4)
[1] 1 1 1 2
And as a proof, back in R, if we set the seed, we can generate exactly the same numbers:
R> set.seed(42)
R> cumsum(rpois(3, 0.3))
[1] 1 2 2
R> cumsum(rpois(4, 0.4))
[1] 1 1 1 2
R>
double *
or an R vectorREALSXP
. – Retrieve