Re: [R] Sending "..." to a C external

2008-08-25 Thread Douglas Bates
On Mon, Aug 25, 2008 at 12:28 PM, John Tillinghast <[EMAIL PROTECTED]> wrote:
>
>
> On Sat, Aug 23, 2008 at 11:46 AM, Douglas Bates <[EMAIL PROTECTED]> wrote:
>
> I don't think it is necessary to go through the agonies of dealing
> with the argument list in a .External call., which is what I assume
> you are doing. (You haven't given us very much information on how you
> are trying to pass the ... argument and such information would be very
> helpful.  The readers of this list are quite intelligent but none, as
> far as I know, have claimed to be telepathic.)
> ---

> This is the first project for which I've tried to write C code for R.
> I am so innocent that I don't even know what I have to explain to get help.

> This is to speed up a friend's R package (BB), which is for general-purpose
> continuous optimization. So it has to do many of the same things as nlm or
> optim: take a function provided by the user, which might have any number of
> arguments, and optimize over one (vector) argument.
> As with optim, this C code will pass all the arguments for the user-provided
> R function back into R, over and over.
> I am open to any suggestions about how to do this simply and efficiently.

In this sort of programming, "simply" is rarely achievable.

Looking at the code in the BB package on CRAN it seems that the
current version is written entirely in R and the calls to the
objective function are created by code like

fargs <- list(...)

Fnew <- do.call("fn", append(list(xnew), fargs))

One way to accomplish this in C code is to create an environment in
which to evaluate the function and then to create a function call to
be evaluated in that environment.  Creating a function call is not
always that easy, however.  It is sometimes easier to pass an
expression or a formula as the "fn" argument because you can then
strip out the function call without needing to construct it.  Consider

> str(expression(foo(x, y = 30))[[1]])
 language foo(x, y = 30)
> str((~ foo(x, y = 30))[[2]])
 language foo(x, y = 30)

Once you have the function call (which is what a language object is),
you decide which argument has not been specified or, more simply, you
require that the first argument be some name like 'x' and that this is
the argument that will be varied by the optimizer.

One way to do this with formulas is

formeval <- function(par, form)
{
stopifnot(inherits(form, "formula"), length(form) == 2)
fc <- form[[2]] # the function call
env <- new.env(parent = environment(form)) # its environment
stopifnot(is.name(fc[[2]]),
  as.character(fc[[2]]) == "x")
assign("x", par, env = env)
eval(fc, env)
}

Then

> foo <- function(x, y = 40) x + y
> formeval(1:3, ~ foo(x))
[1] 41 42 43
> formeval(1:3, ~ foo(x, y = 3))
[1] 4 5 6
> y <- 6
> formeval(1:3, ~ foo(x, y))
[1] 7 8 9

Once you have checked that the function call and the environment are
as you want you can pass them through the .Call interface to a C
function.  In the C function you use FindVarInFrame to determine the
SEXP named "x" in the environment then check that it is numeric and
keep rewriting the value of the REAL pointer and forcing an evaluation
of the function call in that environment.

As I said, "simply" is not usually achievable.  Further discussion
should probably move to the R-devel list.

>> On Fri, Aug 22, 2008 at 2:16 PM, John Tillinghast <[EMAIL PROTECTED]>
>> wrote:
>> > I'm trying to figure this out with "Writing R Extensions" but there's
>> > not a
>> > lot of detail on this issue.
>> > I want to write a (very simple really) C external that will be able to
>> > take
>> > "..." as an argument.
>> > (It's for optimizing a function that may have several parameters besides
>> > the
>> > ones being optimized.)
>>
>> > I got the "showArgs" code (from R-exts) to compile and install, but it
>> > only
>> > gives me error messages when I run it. I think I'm supposed to pass it
>> > different arguments from what I'm doing, but I have no idea which ones.
>>
>> > What exactly are CAR, CDR, and CADR anyway? Why did the R development
>> > team
>> > choose this very un-C-like set of commands? They are not explained much
>> > in
>> > R-exts.
>>
>> Emmanuel has answered that - very engagingly too.  On the train from
>> Dortmund to Dusseldorf last week I was describing exactly that
>> etymology of the names CAR, CDR, CDDR, ... to my companions but I got
>> it wrong.  I had remembered CDR as "contents of the data register" but
>> Emmanuel is correct that it was "contents of the decrement register".
>>
>>
>>
>> The way that I would go about this is using .Call in something like
>>
>> .Call("myCfunction", arg1, arg2, dots = list(...), PACKAGE = "myPackage")
>>
>> Then in your C code you check the length and the names of the dots
>> argument and take appropriate action.
>>
>> An alternative, if you want to use the ... arguments in an R
>> expression to be evaluated by your optimizer, is to create an
>> environment, assign 

Re: [R] Sending "..." to a C external

2008-08-25 Thread John Tillinghast
On Sat, Aug 23, 2008 at 11:46 AM, Douglas Bates <[EMAIL PROTECTED]> wrote:

I don't think it is necessary to go through the agonies of dealing
with the argument list in a .External call., which is what I assume
you are doing. (You haven't given us very much information on how you
are trying to pass the ... argument and such information would be very
helpful.  The readers of this list are quite intelligent but none, as
far as I know, have claimed to be telepathic.)
---

This is the first project for which I've tried to write C code for R.
I am so innocent that I don't even know what I have to explain to get help.

This is to speed up a friend's R package (BB), which is for general-purpose
continuous optimization. So it has to do many of the same things as nlm or
optim: take a function provided by the user, which might have any number of
arguments, and optimize over one (vector) argument.
As with optim, this C code will pass all the arguments for the user-provided
R function back into R, over and over.
I am open to any suggestions about how to do this simply and efficiently.

On Fri, Aug 22, 2008 at 2:16 PM, John Tillinghast <[EMAIL PROTECTED]> wrote:
> > I'm trying to figure this out with "Writing R Extensions" but there's not
> a
> > lot of detail on this issue.
> > I want to write a (very simple really) C external that will be able to
> take
> > "..." as an argument.
> > (It's for optimizing a function that may have several parameters besides
> the
> > ones being optimized.)
>
> > I got the "showArgs" code (from R-exts) to compile and install, but it
> only
> > gives me error messages when I run it. I think I'm supposed to pass it
> > different arguments from what I'm doing, but I have no idea which ones.
>
> > What exactly are CAR, CDR, and CADR anyway? Why did the R development
> team
> > choose this very un-C-like set of commands? They are not explained much
> in
> > R-exts.
>
> Emmanuel has answered that - very engagingly too.  On the train from
> Dortmund to Dusseldorf last week I was describing exactly that
> etymology of the names CAR, CDR, CDDR, ... to my companions but I got
> it wrong.  I had remembered CDR as "contents of the data register" but
> Emmanuel is correct that it was "contents of the decrement register".
>
>
>
> The way that I would go about this is using .Call in something like
>
> .Call("myCfunction", arg1, arg2, dots = list(...), PACKAGE = "myPackage")
>
> Then in your C code you check the length and the names of the dots
> argument and take appropriate action.
>
> An alternative, if you want to use the ... arguments in an R
> expression to be evaluated by your optimizer, is to create an
> environment, assign the elements of list(...) to the appropriate names
> in that environment and pass the environment through .Call to be used
> as the evaluation environment for your R expression.  There is a
> somewhat complicated example of this in the nlmer function in the lme4
> package which you can find at http://lme4.r-forge.r-project.org/.
> However, I don't feel embarrassed about the example being complicated.
>  This is complex stuff and it is not surprising that it isn't
> completely straightforward to accomplish. If you feel that this is
> opaque in R i can hardly wait to see what you think about writing the
> SPSS version.
>

[[alternative HTML version deleted]]

__
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.


Re: [R] Sending "..." to a C external

2008-08-23 Thread Douglas Bates
On Fri, Aug 22, 2008 at 2:16 PM, John Tillinghast <[EMAIL PROTECTED]> wrote:
> I'm trying to figure this out with "Writing R Extensions" but there's not a
> lot of detail on this issue.
> I want to write a (very simple really) C external that will be able to take
> "..." as an argument.
> (It's for optimizing a function that may have several parameters besides the
> ones being optimized.)

> I got the "showArgs" code (from R-exts) to compile and install, but it only
> gives me error messages when I run it. I think I'm supposed to pass it
> different arguments from what I'm doing, but I have no idea which ones.

> What exactly are CAR, CDR, and CADR anyway? Why did the R development team
> choose this very un-C-like set of commands? They are not explained much in
> R-exts.

Emmanuel has answered that - very engagingly too.  On the train from
Dortmund to Dusseldorf last week I was describing exactly that
etymology of the names CAR, CDR, CDDR, ... to my companions but I got
it wrong.  I had remembered CDR as "contents of the data register" but
Emmanuel is correct that it was "contents of the decrement register".

I don't think it is necessary to go through the agonies of dealing
with the argument list in a .External call., which is what I assume
you are doing. (You haven't given us very much information on how you
are trying to pass the ... argument and such information would be very
helpful.  The readers of this list are quite intelligent but none, as
far as I know, have claimed to be telepathic.)

The way that I would go about this is using .Call in something like

.Call("myCfunction", arg1, arg2, dots = list(...), PACKAGE = "myPackage")

Then in your C code you check the length and the names of the dots
argument and take appropriate action.

An alternative, if you want to use the ... arguments in an R
expression to be evaluated by your optimizer, is to create an
environment, assign the elements of list(...) to the appropriate names
in that environment and pass the environment through .Call to be used
as the evaluation environment for your R expression.  There is a
somewhat complicated example of this in the nlmer function in the lme4
package which you can find at http://lme4.r-forge.r-project.org/.
However, I don't feel embarrassed about the example being complicated.
 This is complex stuff and it is not surprising that it isn't
completely straightforward to accomplish. If you feel that this is
opaque in R i can hardly wait to see what you think about writing the
SPSS version.

__
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.


Re: [R] Sending "..." to a C external

2008-08-23 Thread Barry Rowlingson
2008/8/22 Emmanuel Charpentier <[EMAIL PROTECTED]>:
> Le vendredi 22 août 2008 à 15:16 -0400, John Tillinghast a écrit :
>> I'm trying to figure this out with "Writing R Extensions" but there's not a
>> lot of detail on this issue.
>> I want to write a (very simple really) C external that will be able to take
>> "..." as an argument.
>> (It's for optimizing a function that may have several parameters besides the
>> ones being optimized.)
>
> !!! That's a hard one. I have never undertaken this kind of job, but I expect
> that your "..." argument, if you can reach it from C (which I don't know) will
> be bound to a Lisp-like structure, notoriously hard to decode in C. Basically,
> you'll have to create very low level code (an duplicate a good chunk of the R
> parser-interpreter...).
>
> I'd rather treat the "..." argument in a wrapper that could call the relevant
> C function with all arguments interpreted and bound... This wrapper would
> probably be an order of magnitude slower than C code, but two orders of 
> magnitude
> easier to write (and maintain !). Since "..." argument parsing would be done 
> *once*
> before the "grunt work" is accomplished by C code, the slowdown would 
> (probably)
> be negligible...

 I think you're overstating the problem somewhat! Everything you need
to process "..." in C is pretty much in the showArgs function in the
R-ext help. The problem is that John's not told us what his error was!

 It works for me:

 > showArgs(x=2,y=3,z=4)
 [1] 'x' 2.00
 [2] 'y' 3.00
 [3] 'z' 4.00
 NULL
 > showArgs(x=2,y=3,z="s")
 [1] 'x' 2.00
 [2] 'y' 3.00
 [3] 'z' s
 NULL

 But I can get an error if I don't name an argument:

 > showArgs(x=2,y=3,"s")
 [1] 'x' 2.00
 [2] 'y' 3.00
 Error in showArgs(x = 2, y = 3, "s") :
   CHAR() can only be applied to a 'CHARSXP', not a 'NULL'

But that's just because the C doesn't check for this.

 Is that what you're getting? What errors are you getting?

Barry

[this was on an R 2.7.0 I had kicking around, so maybe changed for
later versions...]

__
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.


Re: [R] Sending "..." to a C external

2008-08-22 Thread Emmanuel Charpentier
Le vendredi 22 août 2008 à 15:16 -0400, John Tillinghast a écrit :
> I'm trying to figure this out with "Writing R Extensions" but there's not a
> lot of detail on this issue.
> I want to write a (very simple really) C external that will be able to take
> "..." as an argument.
> (It's for optimizing a function that may have several parameters besides the
> ones being optimized.)

!!! That's a hard one. I have never undertaken this kind of job, but I expect 
that your "..." argument, if you can reach it from C (which I don't know) will 
be bound to a Lisp-like structure, notoriously hard to decode in C. Basically,
you'll have to create very low level code (an duplicate a good chunk of the R
parser-interpreter...). 

I'd rather treat the "..." argument in a wrapper that could call the relevant 
C function with all arguments interpreted and bound... This wrapper would
probably be an order of magnitude slower than C code, but two orders of 
magnitude
easier to write (and maintain !). Since "..." argument parsing would be done 
*once*
before the "grunt work" is accomplished by C code, the slowdown would (probably)
be negligible...

> I got the "showArgs" code (from R-exts) to compile and install, but it only
> gives me error messages when I run it. I think I'm supposed to pass it
> different arguments from what I'm doing, but I have no idea which ones.
> 
> What exactly are CAR, CDR, and CADR anyway? Why did the R development team
> choose this very un-C-like set of commands? 

'Cause they are fundamental to the Lisp-like language that is S/R. Read on...

> They are not explained much in
> R-exts.

At the risk of incurring the R-help deities wrath :

"In the beginning, John Mc Carthy created Lisp 1.5, who begat MACLISP who begat 
..., who begat Scheme ... ". Nonwhistanding a long inheritance story, full of 
sound,
fury, holy wars and bastardry (sometimes evoking European royalty lines...), 
all 
Lisp-like language bear one mark (dominant allele) of their common ancestor, 
which
is the list structure. This structure is implemented as a pair of pointers, the
first one  pointing to the first element of the list, the second pointing to ...
the list of the rest of the members (or nothing, aka NIL).

In McCarthy's implementation, which was machine code on an IBM 704 (we were in 
1957, 
mind you...) such  word was spanned among different parts of a CPU word, known 
in the
technical documentation of this dinosaur as "address register" and "decrement 
register
respectively. Thus the mnemonic names of "Content of the Address Register" and 
"Content
of Decrement Register" (aka "CAR" and "CDR") for these two pointers, names 
which were
used for the (lisp) functions allowing to access them.

Those names have stuck mainly for historical (sentimental ? hysterical ? ) 
reasons.
Even when "reasonable" synonyms were introduced (e. g. "first" and "rest" in 
Common Lisp),
all the old hands (and young dummies who wanted to emulate them) kept "car" and 
"cdr" close
to their hearts.

So, fifty one years after McCarthy stroke of genius, this piece of CS snobbery 
is still
with us (and probably will 'til 64-bit Linux time counters roll over...).

Despite its C-like syntax, its huge collection of array and array-like 
structures,
its loops, S and R are fundamentally Lisp-like languages. Most notably, the 
representation
of executable code is accessible by the code itself : one can create a function 
which
computes another function. Lisp was the first language explicitly created for 
this
purpose, and  it is no happenstance that it (or one of his almost uncountable 
dialects)
that many (most ?) of such language use Lisp fundamentals. Many of R/S "common 
way of
doing things" have a Lisp smell : for example, it is no chance that 
{s|t|l}apply(),
outer() and suchlike are *way* more efficient than for(), and they are strongly
reminescent of Lisp's mapcar...

BTW, this ability to "compute the language" is probably the most fundamental 
point
distinguishing S/R from all the rest of "statistical packages" (SPSS, Stata, 
SAS and
the rest of the crowd...

Now I have to say that I'm not old enough to have first-hand knowledge of this 
history.
I was born, but not weaned, when McCarthy unleashed Lisp on an unsuspecting 
world ...
I learned that ca. 1978-9, while discovering VLisp. 

While I can't really help you (I still think that processing "..." at C level 
is either
hubris of the worst sort, pure folly or a desperate case), I hope to have 
entertained you.

Sincerely,

Emmanuel Charpentier

__
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.


[R] Sending "..." to a C external

2008-08-22 Thread John Tillinghast
I'm trying to figure this out with "Writing R Extensions" but there's not a
lot of detail on this issue.
I want to write a (very simple really) C external that will be able to take
"..." as an argument.
(It's for optimizing a function that may have several parameters besides the
ones being optimized.)

I got the "showArgs" code (from R-exts) to compile and install, but it only
gives me error messages when I run it. I think I'm supposed to pass it
different arguments from what I'm doing, but I have no idea which ones.

What exactly are CAR, CDR, and CADR anyway? Why did the R development team
choose this very un-C-like set of commands? They are not explained much in
R-exts.

Thanks in advance for any info.

John

[[alternative HTML version deleted]]

__
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.