Re: [Rd] C function with unknown output length

From: Dirk Eddelbuettel <edd_at_debian.org>
Date: Wed, 06 Jun 2007 13:19:58 -0500

Salut Vincent,

On 6 June 2007 at 13:17, 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 haven't been on the 'Dirk tells everybody to use RcppTemplate' soapbox lately, so let me (drumroll) suggest to use RcppTemplate.

So if you were to consider C++, which can be done incrementally relative to C, then you could collect your data in a self-growing, autonagically managemed STL Vector, pass it to RcppTemplate, and you're done. I have a local .deb package for r-cran-rcpptemplate I can send you (and which I should upload to Debian), or you can just use it from source on CRAN. You want the source for the examples anyway.

If C++ is not an option, then I typically just hunt for decent examples that do similar stuff. BDR's RODBC is usually a good source -- he also does not know ex ante how long the return sets are. It's not _that_ hard, just tedious. You examine the length of your vector, assign a new one for results of that length, and copy elements.

As an example, see the following from my rdieharder package (that is pending an upload to CRAN) where C as opposed to C++ was a given constraint. I wrote this in a hurry and I may well have missed something to make it a tad better -- but as indicated above, I'd rather be doing it in C++ anyway.

In the code, element [1] is a vector of possibly varying size:

  /* vector of size three: [0] is scalar ks_pv, [1] is pvalues vec, [2] name */   PROTECT(result = allocVector(VECSXP, 3));   /* alloc scalar, and set it */
  PROTECT(pv = allocVector(REALSXP, 1));   REAL(pv)[0] = testptr->ks_pvalue;
  /* vector and set it */
  PROTECT(vec = allocVector(REALSXP, testptr->psamples));   for (i = 0; i < testptr->psamples; i++) {     REAL(vec)[i] = testptr->pvalues[i];
  }
  PROTECT(name = allocVector(STRSXP, 1));   SET_STRING_ELT(name, 0, mkChar(dtestptr->name));

  /* insert scalar and vector */

  SET_VECTOR_ELT(result, 0, pv);
  SET_VECTOR_ELT(result, 1, vec);
  SET_VECTOR_ELT(result, 2, name);
  

  UNPROTECT(4);
  return result;

and testptr->psamples has the unknonw 'N' of vector length.

And yes, we need better cookbook examples for all this.

Hth, Dirk

-- 
Hell, there are no rules here - we're trying to accomplish something. 
                                                  -- Thomas A. Edison

______________________________________________
R-devel_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Received on Wed 06 Jun 2007 - 18:22:14 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 Wed 06 Jun 2007 - 20:36:26 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.