From simon.urbanek at r-project.org  Mon Jun  6 16:21:52 2011
From: simon.urbanek at r-project.org (Simon Urbanek)
Date: Mon, 6 Jun 2011 10:21:52 -0400
Subject: [Rd] C-Side: Applying a function (given as param) to data
	(given as param)
In-Reply-To: <20110605162220.GJ4328@siouxsie>
References: <20110603101712.GD6048@siouxsie>
	<BANLkTi=DkQzC74HP5WEiN-eyBiBV0yUDew@mail.gmail.com>
	<20110603201955.GA2058@siouxsie> <4DEA1C2C.6060504@gmail.com>
	<20110605162220.GJ4328@siouxsie>
Message-ID: <7EB6D92E-9A5C-459A-B4DB-66FC7BEC1AF4@r-project.org>


On Jun 5, 2011, at 12:22 PM, oliver wrote:

> On Sat, Jun 04, 2011 at 07:51:08AM -0400, Duncan Murdoch wrote:
>> On 11-06-03 4:19 PM, oliver wrote:
>>> On Fri, Jun 03, 2011 at 11:14:39AM -0500, Douglas Bates wrote:
>>>> On Fri, Jun 3, 2011 at 5:17 AM, oliver<oliver at first.in-berlin.de>  wrote:
>>>>> Hello,
>>>>> 
>>>>> I'm implementing a package (C-extension),
>>>>> where one function gets data and a function
> [...]
> 
> [...]
>>>> to be in The R Journal.  They show an explicit example of apply in
>>>> compiled code (C++ using the Rcpp structures, in their case).
>>> 
>>> 
>>> As just mentioned: I already created successfully a C-extension for R.
>>> 
>>> But I would like to know, how to call a function that I get via
>>> SEXP as parameter. How can I find out the function definition,
>>> for example the arity of the function and which arguments
>>> a function uses.
>> 
>> You should almost certainly do this in R, not in C.  If you are
>> doing it in C code you'll just be duplicating the implementation
>> from R, and your code will break if that implementation ever
>> changes.
> [...]
> 
> The reason why I wanted to do this in C, not in R,
> is speed as well as consistency.
> 
> I have about 700 MB data that I want to analyse....
> 
> And loops might be to slow in R.
> Some of the apply functions might help and I already implemented
> some stuff in R, but the result values that some of the apply functions give me,
> are changing under certain circumstances, for example list or matrix or vector.
> Also a lot of conversions and value-extracting is needed.
> It looked to me as if doing in C would be the better way.
> 
> So I want to have the possibility to do that in C,
> then loops are no problem, and I can create a certain
> result value type, as well as some other features I have in mind.
> Also in R the automatic coercion to some types sometimes
> is not necessary, and working on the raw values might be
> better, it seems to me.
> 
> Also I want to learn the C-interface, so that in later cases
> I know how to use it.
> 
> For simple values I already know how to use it.
> But the problem is there, when functions are given as parameters.
> That is a very powerful feature. If that only is manageable easy in
> R, it might always be a performance bottleneck.
> 

One thing you should realize is that when you pass a function it is a *R* function (closure) so you are already leaving the C level the moment you need to use it (=evaluate it). Note that loops are not slow in general in R, they are slow compared to scalar computations but that's not the case here so I don't expect much difference in speed, either.

That said, if you get something like function(x) passed via .Call as SEXP the way to use it is simply:

SEXP useMe(SEXP myFun) {
	SEXP xValue = ... /* value to pass ... */
	SEXP env = ... /* where to eval ...* /
	SEXP result = eval(lang2(myFun, xValue), env);
}

so a trivial sort of lapply for a sequence would be something like

SEXP lapply10(SEXP myFun) {
	SEXP sIndex = PROTECT(allocVector(INTSXP, 1));
	SEXP result = PROTECT(allocVector(VECSXP, 10));
	int *index = INTEGER(sIndex);
	for (int i = 0; i < 10; i++) {
		index[0] = i + 1;
		SET_VECTOR_ELT(result, i, eval(lang2(myFun, sIndex), R_GlobalEnv));
	}
	UNPROTECT(2);
	return result;
}

Cheers,
Simon


> 
>> 
>> In R you use formals(fn) to extract the function header.
> 
> OK, thanks.
> 
> 
>> 
>>> 
>>> The problem is, that the C-standard (at least the first ANSI-C standard)
>>> does not guarantee portability for C-pointers.
>>> To be portable, for example the function pointer you use must
>>> definitely be of same type as the function you use.
>>> 
>>> So I need to know how I can use the SEXP-function pointers.
>> 
>> They are not function pointers, they are pointers to R objects.
> [...]
> 
> Aha, good to know.
> 
> Do I have to look at S3 and S4 methods and classses, if I wish to
> make it in C?
> 
> Ciao,
>   Oliver
> 
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
> 
> 



[Rd] C-Side: Applying a function (given as param) to data (given as param)
Simon Urbanek