Re: [Rd] C function with unknown output length

From: Bill Dunlap <bill_at_insightful.com>
Date: Wed, 06 Jun 2007 14:30:28 -0700 (PDT)

On Wed, 6 Jun 2007, Vincent Goulet wrote:

> Could anyone point me to one or more examples in the R sources of a C
> function that is called without knowing in advance what will be the
> length (say) of the output vector?
>
> To make myself clearer, we have a C function that computes
> probabilities until their sum gets "close enough" to 1. Hence, the
> number of probabilities is not known in advance.
>
> I would like to have an idea what is the best way to handle this
> situation in R.

I think you will want to use the .Call(), not .C(), interface. Then you can expand the output vector as you see fit. E.g., the following sets the output vector length to 0 and adds 1 to it each time it needs to. This works in both R and Splus 8.0.

In Splus SET_LENGTH(vec, len) reserves some extra space (above the 'len' requested items) so that future calls to expand it a bit don't always copy it. In R, each call to SET_LENGTH appears to copy the input vector, so you probably want to add extra logic to reserve some extra space and finally trim it down to the precise size you want.

#include <R.h>
#include <Rdefines.h>

/* .Call("unknownReturnLength", 0.02) : return
 * sequence of random uniforms, quitting when
 * you see the first one below 0.02.
 */

SEXP unknownReturnLength(SEXP prob_p)
{

   int retval_length ; /* long preferred in S-PLUS */    double prob, r ;
   SEXP retval ;
   retval_length = 0 ;
   /* how does PROTECT interact with SET_LENGTH? */    PROTECT(retval = NEW_NUMERIC(retval_length)) ;    prob = asReal(prob_p);
   GetRNGstate();
   while((r=unif_rand()) >= prob) {

      double *oldptr = NUMERIC_POINTER(retval) ;
      retval_length++ ;
      SET_LENGTH(retval, retval_length) ;
      if (oldptr != NUMERIC_POINTER(retval))
        Rprintf("expanding retval from %d to %d moved it\n", retval_length-1, retval_length) ;
      NUMERIC_POINTER(retval)[retval_length-1] = r ;
   }
   PutRNGstate();
   return retval ;
}

Bill Dunlap
Insightful Corporation
bill at insightful dot com
360-428-8146

 "All statements in this message represent the opinions of the author and do  not necessarily reflect Insightful Corporation policy or position."



R-devel_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel Received on Wed 06 Jun 2007 - 21:31:27 GMT

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.2.0, at Thu 07 Jun 2007 - 09:34:10 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-devel. Please read the posting guide before posting to the list.