Skip to content

[Rcpp-devel] How to pf from Rcpp

7 messages · Douglas Bates, Hao Xiong, Dirk Eddelbuettel

#
Hi,

I need to use pf() from Rcpp but I couldn't seem to find out how.

For example, the code looks like this:

#include <Rcpp.h>
...
 Rcpp::pf(1.2, 5, 2);
...
The compiler couldn't find pf(). I also tried all arguments as doubles,
but no go.

I also would like to computer the upper tail probability but again
I don't know the exact function signature, so I plan to just use 1-pf(...).

Thanks for your help.
Hao
#
Check the declarations in the include file

Rmath.h

The function must be called as Rf_pf in Rcpp and has the signature

double Rf_pf(double x, double df1, double df2, int lower_tail, int log_p)
On Sat, Nov 12, 2011 at 1:09 AM, Hao Xiong <hao at biostat.ucsf.edu> wrote:
#
On 12 November 2011 at 08:58, Douglas Bates wrote:
| Check the declarations in the include file
| 
| Rmath.h
| 
| The function must be called as Rf_pf in Rcpp and has the signature
| 
| double Rf_pf(double x, double df1, double df2, int lower_tail, int log_p)
|
| On Sat, Nov 12, 2011 at 1:09 AM, Hao Xiong <hao at biostat.ucsf.edu> wrote:
| > Hi,
| >
| > I need to use pf() from Rcpp but I couldn't seem to find out how.
| >
| > For example, the code looks like this:
| >
| > #include <Rcpp.h>
| > ...
| > ?Rcpp::pf(1.2, 5, 2);
| > ...
| > The compiler couldn't find pf(). I also tried all arguments as doubles,
| > but no go.
| >
| > I also would like to computer the upper tail probability but again
| > I don't know the exact function signature, so I plan to just use 1-pf(...).

Beside Doug's tip of falling back to the C API of R, we also have "R sugar"
variants. However these mimic how the R functions are implemented, rather
than than the APIthey provide --- and more important 'pf' actually becomes
'pnf' because what we usually want as 'f' is the non-central f, ie f with
argument ncp=0:


R> suppressMessages(library(inline))
R> suppressMessages(library(Rcpp))
R> 
R> fun <- cxxfunction(signature(x_="numeric", df_="numeric"), body='
+    NumericVector x(x_);
+    NumericVector df(df_);
+    NumericVector res = pnf(x, df(0), df(1), 0, 1);
+    return(wrap(res));
+ ',plugin="Rcpp")
R> 
R> 
R> fun(1:3, c(6,8))                ## our function
[1] 0.514760 0.820800 0.923255
R> 
R> pf(1:3, 6, 8)                   ## equivalent R call
[1] 0.514760 0.820800 0.923255
R> 
R> pf(1:3, 6, 8, 0)                ## idem with ncp=0
[1] 0.514760 0.820800 0.923255
R> 

The nice things is that the sugar version vectorised. The not so nice thing
is that you _must_ supply the extra arguments for lower tail and log.

Dirk


| >
| > Thanks for your help.
| > Hao
| > _______________________________________________
| > Rcpp-devel mailing list
| > Rcpp-devel at lists.r-forge.r-project.org
| > https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
| >
| _______________________________________________
| Rcpp-devel mailing list
| Rcpp-devel at lists.r-forge.r-project.org
| https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
#
Thank you, Dirk and Douglas. You both provided the answers I need.
On 11/12/2011 12:05 PM, Dirk Eddelbuettel wrote:
Can you tell me in which file is pnf() declared? It would help me later 
when I need
to look up similar functions for other distributions.

Thanks for answering my question. Rcpp has been a God-sent for me.

Hao
#
Sorry about the typos and grammar. One day I'll learn to proof-read. Edited
version below.
On 12 November 2011 at 14:05, Dirk Eddelbuettel wrote:
| Beside Doug's tip of falling back to the C API of R, we also have "Rcpp sugar"
| variants. However these mimic how the R functions are implemented, rather
| than micking the API they provide --- for example 'pf' actually becomes
| 'pnf' because what we usually want as 'f' is the non-central f, ie f with
| argument ncp=0:
| 
| 
| R> suppressMessages(library(inline))
| R> suppressMessages(library(Rcpp))
| R> 
| R> fun <- cxxfunction(signature(x_="numeric", df_="numeric"), body='
| +    NumericVector x(x_);
| +    NumericVector df(df_);
| +    NumericVector res = pnf(x, df(0), df(1), 0, 1);
| +    return(wrap(res));
| + ',plugin="Rcpp")
| R> 
| R> 
| R> fun(1:3, c(6,8))                ## our function
| [1] 0.514760 0.820800 0.923255
| R> 
| R> pf(1:3, 6, 8)                   ## equivalent R call
| [1] 0.514760 0.820800 0.923255
| R> 
| R> pf(1:3, 6, 8, 0)                ## idem with ncp=0
| [1] 0.514760 0.820800 0.923255
| R> 
| 
| The nice thing is that the sugar versions are vectorised. The not so nice thing
| is that you _must_ supply the extra arguments for lower tail and log.

What I did here is what I'd recommend. Set up a working example in R, then
maybe expand the arguments:

R> pf(1:3, 6, 8, ncp=0, lower=1, log=0)
[1] 0.514760 0.820800 0.923255
R> 

and given that, look into (unfortunately somewhat underdocumented) Rcpp sugar
functions for statistics.

Dirk
#
On 12 November 2011 at 12:47, Hao Xiong wrote:
| Thank you, Dirk and Douglas. You both provided the answers I need.
|
| On 11/12/2011 12:05 PM, Dirk Eddelbuettel wrote:
| > Beside Doug's tip of falling back to the C API of R, we also have "R sugar"
| > variants. However these mimic how the R functions are implemented, rather
| > than than the APIthey provide --- and more important 'pf' actually becomes
| > 'pnf' because what we usually want as 'f' is the non-central f, ie f with
| > argument ncp=0:
| >
| >
| > R>  suppressMessages(library(inline))
| > R>  suppressMessages(library(Rcpp))
| > R>
| > R>  fun<- cxxfunction(signature(x_="numeric", df_="numeric"), body='
| > +    NumericVector x(x_);
| > +    NumericVector df(df_);
| > +    NumericVector res = pnf(x, df(0), df(1), 0, 1);
| > +    return(wrap(res));
| > + ',plugin="Rcpp")
| > R>
| > R>
| > R>  fun(1:3, c(6,8))                ## our function
| > [1] 0.514760 0.820800 0.923255
| > R>
| > R>  pf(1:3, 6, 8)                   ## equivalent R call
| > [1] 0.514760 0.820800 0.923255
| > R>
| > R>  pf(1:3, 6, 8, 0)                ## idem with ncp=0
| > [1] 0.514760 0.820800 0.923255
| > R>
| >
| > The nice things is that the sugar version vectorised. The not so nice thing
| > is that you _must_ supply the extra arguments for lower tail and log.
| Can you tell me in which file is pnf() declared? It would help me later 
| when I need
| to look up similar functions for other distributions.

'grep -r' is often my best friend -- but in this case you need to poke by hand

   include/Rcpp/stats/f.h
   include/Rcpp/stats/nf.h

as all these contains (beside the copyright header) are a mere 

  #ifndef Rcpp__stats__f_h
  #define Rcpp__stats__f_h

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

  #endif

and 

  #ifndef Rcpp__stats__nf_h
  #define Rcpp__stats__nf_h

  RCPP_DPQ_3(nf,::Rf_dnf,::Rf_pnf,::Rf_qnf)

  #endif

which you need strong glasses to read -- basically a 'expand this for us'
factory-style macro is invoked to provide d-p-q variants of f and nf,
respectively, by unrolling the vector elements of the first arguments on the
corresponding Rf_{d,p,n}* functions.
 
As I said, a tad underdocumented. And mostly magic and pixie dust.

| Thanks for answering my question. Rcpp has been a God-sent for me.

Doing MCMC or other Monte Carlo, eh?  ;-)

Dirk
#
On 12 November 2011 at 15:41, Dirk Eddelbuettel wrote:
| 'grep -r' is often my best friend -- but in this case you need to poke by hand
| 
|    include/Rcpp/stats/f.h
|    include/Rcpp/stats/nf.h
| 
| as all these contains (beside the copyright header) are a mere 
| 
|   #ifndef Rcpp__stats__f_h
|   #define Rcpp__stats__f_h
| 
|   RCPP_DPQ_3(f,::Rf_df,::Rf_pf,::Rf_qf)
| 
|   #endif
| 
| and 
| 
|   #ifndef Rcpp__stats__nf_h
|   #define Rcpp__stats__nf_h
| 
|   RCPP_DPQ_3(nf,::Rf_dnf,::Rf_pnf,::Rf_qnf)
| 
|   #endif

What I quoted there contain a minor buglet which I just fixed. Now we can
call pf() without having to set the ncp argument as it should be. I also
added two new unit tests for pf() and pnf().

Thanks to Hao for posting this here as his post triggered the work for the fix.

Dirk