Re: [Rd] (PR#9811) sequence(c(2, 0, 3)) produces surprising results,

2007-07-27 Thread ripley
This is as doumented, and I think you could say the same thing of seq().
BTW, sequence() allows negative inputs, and I don't think you want
sum(input) in that case.

I've never seen the point of sequence(), but it has been around in R for a 
long time.  It is used in packages eRm, extRemes, hydrosanity, klaR, seas.
Who knows what people have in private code, so I don't see any compelling 
case to change it.  If people want a different version, it would only take 
a minute to write (see below).

We could make seq_len take a vector argument, but as you point out in a 
followup that makes it slower in the common case.  It also changes its 
meaning if a length > 1 vector is supplied, and would speed matter in the 
long-vector case?  What does

sequence0 <- function (nvec)
{
 s <- integer(0)
 for (i in nvec) s <- c(s, seq_len(i))
 s
}

not do that is more than a very rare need?


On Thu, 26 Jul 2007, [EMAIL PROTECTED] wrote:

> Full_Name: Bill Dunlap
> Version: 2.5.0
> OS: Linux
> Submission from: (NULL) (70.98.76.47)
>
>
> sequence(nvec) is documented to return
> the concatenation of seq(nvec[i]), for
> i in seq(along=nvec).  This produces inconvenient
> (for me) results for 0 inputs.
>> sequence(c(2,0,3)) # would like 1 2 1 2 3, ignore 0
>[1] 1 2 1 0 1 2 3
> Would changing sequence(nvec) to use seq_len(nvec[i])
> instead of the current 1:nvec[i] break much existing code?
>
> On the other hand, almost no one seems to use sequence()
> and it might make more sense to allow seq_len() and seq()
> to accept a vector for length.out and they would return a
> vector of length sum(length.out),
>c(seq_len(length.out[1]), seq_len(length.out[2]), ...)
>
> __
> R-devel@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

-- 
Brian D. Ripley,  [EMAIL PROTECTED]
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford, Tel:  +44 1865 272861 (self)
1 South Parks Road, +44 1865 272866 (PA)
Oxford OX1 3TG, UKFax:  +44 1865 272595

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] sweep sanity checking?

2007-07-27 Thread Petr Savicky
When I was preparing the patch of sweep submitted on July 25, I was
unaware of the code by Heather Turner. She suggested a very elegant
solution, if STATS is a vector and we want to use meaningful recycling
in full generality. I would like to suggest a combined solution, which
uses Heather Turner's algorithm if check.margin=FALSE (default) and STATS
is a vector and my previous algorithm, if check.margin=TRUE or STATS is
an array. The suggestion is

  # combined from the original code of sweep without warnings and from
  # https://stat.ethz.ch/pipermail/r-help/2005-June/073989.html by Robin Hankin
  # https://stat.ethz.ch/pipermail/r-help/2005-June/074001.html by Heather 
Turner
  # https://stat.ethz.ch/pipermail/r-devel/2007-June/046217.html by Ben Bolker
  # with some further modifications by Petr Savicky
  sweep <- function(x, MARGIN, STATS, FUN = "-", check.margin=FALSE, ...)
  {
  FUN <- match.fun(FUN)
  dims <- dim(x)
  dimmargin <- dims[MARGIN]
  if (is.null(dim(STATS))) {
  dimstats <- length(STATS)
  } else {
  dimstats <- dim(STATS)
  check.margin <- TRUE
  }
  s <- length(STATS)
  if (s > prod(dimmargin)) {
  warning("length of STATS greater than the extent of dim(x)[MARGIN]")
  } else if (check.margin) {
  dimmargin <- dimmargin[dimmargin > 1]
  dimstats <- dimstats[dimstats > 1]
  if (length(dimstats) > length(dimmargin) ||
  any(dimstats != dimmargin[seq(along.with=dimstats)]))
  warning("length(STATS) or dim(STATS) do not match dim(x)[MARGIN]")
  } else {
  cumDim <- c(1, cumprod(dimmargin))
  upper <- min(cumDim[cumDim >= s])
  lower <- max(cumDim[cumDim <= s])
  if (upper %% s != 0 || s %% lower != 0)
  warning("STATS does not recycle exactly across MARGIN")
  }
  perm <- c(MARGIN, (1:length(dims))[ - MARGIN])
  FUN(x, aperm(array(STATS, dims[perm]), order(perm)), ...)
  }

Heather presented four examples testing her code:
  sweep(array(1:24, dim = c(4,3,2)), 1, 1:2)# no warning
  sweep(array(1:24, dim = c(4,3,2)), 1, 1:12)   # no warning
  sweep(array(1:24, dim = c(4,3,2)), 1, 1:24)   # no warning
  sweep(array(1:24, dim = c(4,3,2)), 1:2, 1:3)  # warning
The second and third example are not really correct, since STATS extends
also to dimensions not included in MARGIN. The problem is better visible
for example in
  sweep(array(1:24, dim = c(4,4,3,3,2,2)), c(1,3), 1:12)
where MARGIN clearly has to contain two dimensions explicitly.
So, I use the examples with a larger margin corresponding to STATS
as follows
  sweep(array(1:24, dim = c(4,3,2)), 1, 1:2)# no warning
  sweep(array(1:24, dim = c(4,3,2)), 1:2, 1:12) # no warning
  sweep(array(1:24, dim = c(4,3,2)), 1:3, 1:24) # no warning
  sweep(array(1:24, dim = c(4,3,2)), 1:2, 1:3)  # warning
The current proposal for sweep indeed gives no warning in the first
three examples and gives a warning in the last one.

I did not use the suggestion to call the option warn with default
warn = getOption("warn"). The reason is that there are two
different decisions:
 (1) whether to generate a warning
 (2) what to do with the warning, if it is generated.
The warn option influences (2): the warning may be suppressed,
printed after the return to the top level, printed immediately or
it may be converted to an error. I think that the option
controling (2) should not be mixed with an option which
controls (1). If R has an option controling to which extent
recycling is allowed, then this could be used, but warn
has a different purpose.

I appreciate feedback.

Petr.

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] (PR#9811) sequence(c(2, 0, 3)) produces surprising results,

2007-07-27 Thread Robin Hankin

On 27 Jul 2007, at 08:07, [EMAIL PROTECTED] wrote:

> This is as doumented, and I think you could say the same thing of  
> seq().
> BTW, sequence() allows negative inputs, and I don't think you want
> sum(input) in that case.
>
> I've never seen the point of sequence(), but it has been around in  
> R for a
> long time.  It is used in packages eRm, extRemes, hydrosanity,  
> klaR, seas.
> Who knows what people have in private code, so I don't see any  
> compelling
> case to change it.  If people want a different version, it would  
> only take
> a minute to write (see below).
>
> We could make seq_len take a vector argument, but as you point out  
> in a
> followup that makes it slower in the common case.  It also changes its
> meaning if a length > 1 vector is supplied, and would speed matter  
> in the
> long-vector case?  What does
>
> sequence0 <- function (nvec)
> {
>  s <- integer(0)
>  for (i in nvec) s <- c(s, seq_len(i))
>  s
> }
>
> not do that is more than a very rare need?
>


My 2 cents:

  Defining

mySequence <- function(x){unlist(sapply(x,function(i){seq_len 
(i)}))}

is much faster.

Neither sequence0()  nor  mySequence() accepts vectors with any  
element <0
although as Brian Ripley points out, sequence() itself does (which I  
think is
undesirable).






Robin Hankin
Uncertainty Analyst
National Oceanography Centre, Southampton
European Way, Southampton SO14 3ZH, UK
  tel  023-8059-7743

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Rd2dvi (PR#9812)

2007-07-27 Thread ripley
It seems this feature was introduced in Perl 5.6.1, but that is older than 
Solaris 9 (which was first released 9/02 according to www.sun.com).

We need to know what version of Perl this was.


On Thu, 26 Jul 2007, Bill Dunlap wrote:

> On Thu, 26 Jul 2007 [EMAIL PROTECTED] wrote:
>
>> Is this a bug--
>>
>> ---
>> <234>% R CMD Rd2dvi base.Rd
>> Converting Rd files to LaTeX ...
>> base.Rd
>> Can't use an undefined value as filehandle reference at
>> /opt/R-2.5.1/lib/R/share/perl/R/Rdconv.pm line 78.
>
> This may be due to a change I suggested a while back which
> required perl 5.6 (or so) to work.  The change was to ensure
> that the file handle rdfile was closed when Rdconv was done
> with it.  If this is the problem, upgrading perl to 5.8 will
> make it go away.  Rdconv.pm should have a 'use v5.6' (or 5.8?)
> line at the top if it wants to continue to use this syntax.
>
> < open(rdfile, "<$Rdname") or die "Rdconv(): Couldn't open '$Rdfile': 
> $!\n";
> <
> ---
>> open(my $rdfile, "<$Rdname") or die "Rdconv(): Couldn't open '$Rdfile': 
>> $!\n";
>> # Before we added the 'my $' in front of rdfile,
>> # rdfile was not getting closed.   Now it will close
>> # when $rdfile goes out of scope.  (We could have added
>> # a close rdfile at the end of the while(), but
>> # scoping method is more reliable.
> 123c127
> < while(){
> ---
>> while(<$rdfile>){
>
> 
> 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@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

-- 
Brian D. Ripley,  [EMAIL PROTECTED]
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford, Tel:  +44 1865 272861 (self)
1 South Parks Road, +44 1865 272866 (PA)
Oxford OX1 3TG, UKFax:  +44 1865 272595

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] (PR#9811) sequence(c(2, 0, 3)) produces surprising results,

2007-07-27 Thread maechler
> "Robin" == Robin Hankin <[EMAIL PROTECTED]>
> on Fri, 27 Jul 2007 08:33:18 +0100 writes:

Robin> On 27 Jul 2007, at 08:07, [EMAIL PROTECTED]
Robin> wrote:

>> This is as doumented, and I think you could say the same
>> thing of seq().  BTW, sequence() allows negative inputs,
>> and I don't think you want sum(input) in that case.
>> 
>> I've never seen the point of sequence(), but it has been
>> around in R for a long time.  It is used in packages eRm,
>> extRemes, hydrosanity, klaR, seas.  Who knows what people
>> have in private code, so I don't see any compelling case
>> to change it.  If people want a different version, it
>> would only take a minute to write (see below).
>> 
>> We could make seq_len take a vector argument, but as you
>> point out in a followup that makes it slower in the
>> common case.  It also changes its meaning if a length > 1
>> vector is supplied, and would speed matter in the
>> long-vector case?  What does
>> 
>> sequence0 <- function (nvec) { s <- integer(0) for (i in
>> nvec) s <- c(s, seq_len(i)) s }
>> 
>> not do that is more than a very rare need?
>> 


 Robin> My 2 cents:

Robin>   Defining

Robin> mySequence <-
Robin> function(x){unlist(sapply(x,function(i){seq_len(i)}))}

Robin> is much faster.

Robin> Neither sequence0() nor mySequence() accepts vectors
Robin> with any element <0 although as Brian Ripley points
Robin> out, sequence() itself does (which I think is
Robin> undesirable).

Yes, I agree.

Some more historical perspective (Brian alluded to) :

As the third R core member (first after Robert & Ross),
I still have access to the following R version 
{on one very old fortunately still running Solaris machine; I'm
 pretty sure it would not compile anymore on any recent
 OS/compiler suite} :

--
..$ R-0.00alpha

R Alpha-Test Version, Copyright (C) 1995 Robert Gentleman and Ross Ihaka

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type `license()' for details.

> sequence
function (nvec)
{
sequence <- NULL
for (i in (1:length(nvec))) sequence <- c(sequence, seq(nvec[i]))
sequence
}
>  
--

which interestingly also "works" for negative nvec[i],
but the way it is written even more clearly suggests that
negative nvec  entries were not the intent.

I'm voting that R should adopt a new (fast, but R code
only) version of sequence() which gives an error for negative
'nvec' entries --- though I do agree with Brian that it's not
really an important function at all.

Martin Maechler, ETH Zurich

PS: 
  Note that this was before R became GPL'ed "Free software", and
  that the R version stems from the following place -- back in 1995 :

  /[EMAIL PROTECTED]:/pub/R/unix/
  -rw-r--r--  1 51   1371 Jun 20  1995 INSTALL
  -rw-r--r--  1 51 466232 Jun 20  1995 R-unix-src.tar.gz
  -rw-r--r--  1 51   1079 Jun 20  1995 README


__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Using R_MakeExternalPtr

2007-07-27 Thread Hin-Tak Leung
As others as commented, everything going in/out of the .Call() interface
needs to be SEXP (even if it does nothing and you are returning
R_NilValue).

Secondly, your attached code is both (1) too long, and (2) incomplete.

You should write some *simple* R code that
uses only soamInit() and soamUnInit() (the latter is missing and you had 
not included it), Then fill the middle with soamSubmit(). Nobody really
want to read your 60+ line of R code (too long) and incomplete C code
(too short) to work out what's broken. Use complete and short examples
to illustrate your problem!

Also, you seem to take for granted that the typo/length of Argument
in soamSubmit() are those you think they are... e.g. I would put in say, 
for example:

if ((JobID == R_NilValue) || ( TYPEOF(JobID) != INTSXP)) {
 Rprintf("JobID unexpected!\n");
 return R_NilValue;
}

Just to be on the safe side. You may find some surprises there -
trying to do INTEGER() on a REALSXP, or vice versa can be dangerous.

I am still not convinced that your segfault is to do with externalptr -
e.g. the '.Call() must return SEXP' is a basic R extension usage and you
didn't understand that one.

Jonathan Zhou wrote:
> Hi all, 
> 
> Here is the R code function in where I called the two C++ and further below
> are the 2 C++ functions I used to create the externalptr and use it : 
> 
> soam.Rapply <- function (x, func, ...,
>join.method=cbind,
>njobs,
>batch.size=100,
>packages=NULL,
>savelist=NULL)
> {
> if(missing(njobs))
> njobs <- max(1,ceiling(nrow(x)/batch.size))
> 
> if(!is.matrix(x) && !is.data.frame(x))
> stop("x must be a matrix or data frame")
> 
> if(njobs>1)
> {rowSet <- lapply(splitIndices(nrow(x), njobs), function(i) x[i, ,
> drop = FALSE])} else {rowSet <- list(x)}
> 
> sesCon <- .Call("soamInit")
> 
> script <- " "
> 
> fname <- tempfile(pattern = "Rsoam_data", tmpdir = getwd())
> file(fname, open="w+")
> if(!is.null(savelist)) {
> dump(savelist, fname)
> script<-readLines(fname)
> }
> 
> if(!is.null(packages))
> for(counter in 1:length(packages))
> {
> temp<-call("library", packages[counter], character.only=TRUE)
> dput(temp, fname)
> pack.call<-readLines(fname)
> script<-append(script, pack.call)
> }
> 
> for(counter in 1:njobs)
> {
> caller <- paste("caller", counter, sep = "")
> soam.call<-call("dput", call("apply", X=rowSet[[counter]], MARGIN=1,
> FUN=func), caller)
> dput(soam.call, fname)
> soam.call<-readLines(fname)
> 
> temp<-append(script, soam.call)
> final.script = temp[1]
> for(count in 2:length(temp)){
> final.script<-paste(final.script, temp[count], "\n")}
> 
> .Call("soamSubmit", counter, sesCon, final.script, packages)
> }
> 
> .Call("soamGetResults", sesCon, njobs, join.method, parent.frame())
> 
> for(job in 1:njobs)
> {
> caller <- paste("result", job, sep = "")
> temp = dget(caller)
> if(job==1) {retval=temp} else {retval=join.method(retval,temp)}
> }
> 
> .Call("soamUninit")
> 
> retval
> }
> 
> *** Here are the 2 C++ functions: 
> 
> extern "C"
> {
> SEXP soamInit ()
> {
> // Initialize the API
> SoamFactory::initialize();
> 
> // Set up application specific information to be supplied to Symphony
> char appName[] = "SampleAppCPP";
> 
> // Set up application authentication information using the default
> security provider
> DefaultSecurityCallback securityCB("Guest", "Guest");
> 
> // Connect to the specified application
> ConnectionPtr conPtr = SoamFactory::connect(appName, &securityCB);
> 
> // Set up session creation attributes
> SessionCreationAttributes attributes;
> attributes.setSessionName("mySession");
> attributes.setSessionType("ShortRunningTasks");
> attributes.setSessionFlags(SF_RECEIVE_SYNC);
> 
> // Create a synchronous session
> Session* sesPtr = conPtr->createSession(attributes);
> 
> SEXP out = R_MakeExternalPtr((void*)temp, R_NilValue, R_NilValue);
> 
> return out;
> }
> }
> 
> extern "C"
> {
>   void soamSubmit (SEXP jobID,//job ID
>SEXP sesCon,   //session pointer
>SEXP caller,   //objects
>SEXP pack) //packages
> {
>   char* savelist = CHAR(STRING_ELT(caller, 0));
>   string strTemp = "";
>   int job = INTEGER(jobID)[0];
> 
>   void* temp = R_ExternalPtrAddr(sesCon);
> Session* sesPtr = reinterpret_cast(temp);
> 
> // Create a message
>   MyMessage inMsg(job, /*pack,*/ savelist);
> 
> // Send it
> TaskInputHandlePtr input = sesPtr->sendTaskInput(&inMsg);
> }
> }

_