Skip to content

[Rcpp-devel] Is it possible to call an R internal C function from Rcpp?

2 messages · steven pav, Dirk Eddelbuettel

#
hi all;

I want to write the density function for the doubly non-central F
distribution using Rcpp. The algorithm (from Paolella's Intermediate
Probability, listing 10.8) computes the weighted sum of the PDF function of
the singly non-central F distribution. This is available in R via df; the
internal df function is apparently

function (x, df1, df2, ncp, log = FALSE)
{
    if (missing(ncp))
        .External(C_df, x, df1, df2, log)
    else .External(C_dnf, x, df1, df2, ncp, log)
}

Is it possible to call this C_dnf from Rcpp? One thought I had was to use
Rinside, but I want to avoid that overhead if possible.

cheers,
#
On 2 March 2015 at 14:04, steven pav wrote:
| I want to write the density function for the doubly non-central F distribution
| using Rcpp. The algorithm (from Paolella's Intermediate Probability, listing
| 10.8) computes the weighted sum of the PDF function of the singly non-central F
| distribution. This is available in R via df; the internal df function is
| apparently?
| 
| function (x, df1, df2, ncp, log = FALSE)?
| {
| ? ? if (missing(ncp))?
| ? ? ? ? .External(C_df, x, df1, df2, log)
| ? ? else .External(C_dnf, x, df1, df2, ncp, log)
| }
| 
| Is it possible to call this C_dnf from Rcpp? One thought I had was to use
| Rinside, but I want to avoid that overhead if possible.

"Quite possibly" in this particular case as we have both the sugar functions
for df and dnf, and the single-value wrapper of the Rmath functions.

For sugar, definitions are a tad, ahem, "cryptic" for use of macros. From 

  git/rcpp/inst/include/Rcpp/stats/f.h:

      RCPP_DPQ_2(f,::Rf_df,::Rf_pf,::Rf_qf)

  git/rcpp/inst/include/Rcpp/stats/nf.h:
  
      RCPP_DPQ_3(nf,::Rf_dnf,::Rf_pnf,::Rf_qnf)

where the key are '2' and '3' for the number of arguments, as above. These
become sugar functions
  Rcpp::df(), Rcpp::qf(), Rcpp::pf()
and
  Rcpp::dnf(), Rcpp::qnf(), Rcpp::pnf()

And from

  git/rcpp/inst/include/Rcpp/Rmath.h

    /* F Distibution */
    inline double df(double x, double df1, double df2, int lg)		{ return ::Rf_df(x, df1, df2, lg); }

    /* Non-central F Distribution */
    inline double dnf(double x, double df1, double df2, double ncp, int lg)		{ return ::Rf_dnf(x, df1, df2, ncp, lg); }

Give that a whirl, and benchmark carefully against known values.  Once you
have, please do send me a short writeup for the Rcpp Gallery now that we have
mathjax (yay!!) and graphs (yay!!) thanks to Jonathan.

Dirk