On Sun, 30 Oct 2005, Jonathan Rougier wrote: > I'm not sure about this. Perhaps I am a dinosaur, but my feeling is > that if people are writing functions in R that might be subject to > simple operations like outer products, then they ought to be writing > vectorised functions!
I would agree. How about an oapply() function that does multiway (rather than just two-way) outer products. Basing the name on "apply" would emphasize the similarity to other flexible, not particularly optimized second-order functions. -thomas > Maybe it's not possible to hold this line, and > maybe "outer" is not the right place to draw it, but I think we ought to > respect the "x is a vector" mindset as much as possible in the base > package. As Tony notes, the documentation does try to be clear about > what outer actually does, and how it can be used. > > So I am not a fan of the VECTORIZED argument, and definitely not a fan > of the VECTORIZED=FALSE default. > > Jonathan. > > Gabor Grothendieck wrote: >> If the default were changed to VECTORIZED=FALSE then it would >> still be functionally compatible with what we have now so all existing >> software would continue to run correctly yet would not cause >> problems for the unwary. Existing software would not have to be changed >> to add VECTORIZED=TRUE except for those, presumbly few, cases >> where outer performance is critical. One optimization might be to >> have the default be TRUE if the function is * or perhaps if its specified >> as a single character and FALSE otherwise. >> >> Having used APL I always regarded the original design of outer in R as >> permature performance optimization and this would be a chance to get >> it right. >> >> On 10/28/05, Tony Plate <[EMAIL PROTECTED]> wrote: >> >>> [following on from a thread on R-help, but my post here seems more >>> appropriate to R-devel] >>> >>> Would a patch to make outer() work with non-vectorized functions be >>> considered? It seems to come up moderately often on the list, which >>> probably indicates that many many people get bitten by the same >>> incorrect expectation, despite the documentation and the FAQ entry. It >>> looks pretty simple to modify outer() appropriately: one extra function >>> argument and an if-then-else clause to call mapply(FUN, ...) instead of >>> calling FUN directly. >>> >>> Here's a function demonstrating this: >>> >>> outer2 <- function (X, Y, FUN = "*", ..., VECTORIZED=TRUE) >>> { >>> no.nx <- is.null(nx <- dimnames(X <- as.array(X))) >>> dX <- dim(X) >>> no.ny <- is.null(ny <- dimnames(Y <- as.array(Y))) >>> dY <- dim(Y) >>> if (is.character(FUN) && FUN == "*") { >>> robj <- as.vector(X) %*% t(as.vector(Y)) >>> dim(robj) <- c(dX, dY) >>> } >>> else { >>> FUN <- match.fun(FUN) >>> Y <- rep(Y, rep.int(length(X), length(Y))) >>> if (length(X) > 0) >>> X <- rep(X, times = ceiling(length(Y)/length(X))) >>> if (VECTORIZED) >>> robj <- FUN(X, Y, ...) >>> else >>> robj <- mapply(FUN, X, Y, MoreArgs=list(...)) >>> dim(robj) <- c(dX, dY) >>> } >>> if (no.nx) >>> nx <- vector("list", length(dX)) >>> else if (no.ny) >>> ny <- vector("list", length(dY)) >>> if (!(no.nx && no.ny)) >>> dimnames(robj) <- c(nx, ny) >>> robj >>> } >>> # Some examples >>> f <- function(x, y, p=1) {cat("in f\n"); (x*y)^p} >>> outer2(1:2, 3:5, f, 2) >>> outer2(numeric(0), 3:5, f, 2) >>> outer2(1:2, numeric(0), f, 2) >>> outer2(1:2, 3:5, f, 2, VECTORIZED=F) >>> outer2(numeric(0), 3:5, f, 2, VECTORIZED=F) >>> outer2(1:2, numeric(0), f, 2, VECTORIZED=F) >>> >>> # Output on examples >>> >>>> f <- function(x, y, p=1) {cat("in f\n"); (x*y)^p} >>>> outer2(1:2, 3:5, f, 2) >>> >>> in f >>> [,1] [,2] [,3] >>> [1,] 9 16 25 >>> [2,] 36 64 100 >>> >>>> outer2(numeric(0), 3:5, f, 2) >>> >>> in f >>> [,1] [,2] [,3] >>> >>>> outer2(1:2, numeric(0), f, 2) >>> >>> in f >>> >>> [1,] >>> [2,] >>> >>>> outer2(1:2, 3:5, f, 2, VECTORIZED=F) >>> >>> in f >>> in f >>> in f >>> in f >>> in f >>> in f >>> [,1] [,2] [,3] >>> [1,] 9 16 25 >>> [2,] 36 64 100 >>> >>>> outer2(numeric(0), 3:5, f, 2, VECTORIZED=F) >>> >>> [,1] [,2] [,3] >>> >>>> outer2(1:2, numeric(0), f, 2, VECTORIZED=F) >>> >>> [1,] >>> [2,] >>> >>> If a patch to add this feature would be considered, I'd be happy to >>> submit one (including documentation). If so, and if there are any >>> potential traps I should bear in mind, please let me know! >>> >>> -- Tony Plate >>> >>> Rau, Roland wrote: >>> >>>> Dear all, >>>> >>>> a big thanks to Thomas Lumley, James Holtman and Tony Plate for their >>>> answers. They all pointed in the same direction => I need a vectorized >>>> function to be applied. Hence, I will try to work with a 'wrapper' >>>> function as described in the FAQ. >>>> >>>> Thanks again, >>>> Roland >>>> >>>> >>>> >>>> >>>>> -----Original Message----- >>>>> From: Thomas Lumley [mailto:[EMAIL PROTECTED] >>>>> Sent: Thursday, October 27, 2005 11:39 PM >>>>> To: Rau, Roland >>>>> Cc: r-help@stat.math.ethz.ch >>>>> Subject: Re: [R] outer-question >>>>> >>>>> >>>>> You want FAQ 7.17 Why does outer() behave strangely with my function? >>>>> >>>>> -thomas >>>>> >>>>> On Thu, 27 Oct 2005, Rau, Roland wrote: >>>>> >>>>> >>>>> >>>>>> Dear all, >>>>>> >>>>>> This is a rather lengthy message, but I don't know what I >>>>> >>>>> made wrong in >>>>> >>>>> >>>>>> my real example since the simple code works. >>>>>> I have two variables a, b and a function f for which I would like to >>>>>> calculate all possible combinations of the values of a and b. >>>>>> If f is multiplication, I would simply do: >>>>>> >>>>>> a <- 1:5 >>>>>> b <- 1:5 >>>>>> outer(a,b) >>>>>> >>>>>> ## A bit more complicated is this: >>>>>> f <- function(a,b,d) { >>>>>> return(a*b+(sum(d))) >>>>>> } >>>>>> additional <- runif(100) >>>>>> outer(X=a, Y=b, FUN=f, d=additional) >>>>>> >>>>>> ## So far so good. But now my real example. I would like to plot the >>>>>> ## log-likelihood surface for two parameters alpha and beta of >>>>>> ## a Gompertz distribution with given data >>>>>> >>>>>> ### I have a function to generate random-numbers from a >>>>>> Gompertz-Distribution >>>>>> ### (using the 'inversion method') >>>>>> >>>>>> random.gomp <- function(n, alpha, beta) { >>>>>> return( (log(1-(beta/alpha*log(1-runif(n)))))/beta) >>>>>> } >>>>>> >>>>>> ## Now I generate some 'lifetimes' >>>>>> no.people <- 1000 >>>>>> al <- 0.1 >>>>>> bet <- 0.1 >>>>>> lifetimes <- random.gomp(n=no.people, alpha=al, beta=bet) >>>>>> >>>>>> ### Since I neither have censoring nor truncation in this >>>>> >>>>> simple case, >>>>> >>>>> >>>>>> ### the log-likelihood should be simply the sum of the log of the >>>>>> ### the densities (following the parametrization of >>>>> >>>>> Klein/Moeschberger >>>>> >>>>> >>>>>> ### Survival Analysis, p. 38) >>>>>> >>>>>> loggomp <- function(alphas, betas, timep) { >>>>>> return(sum(log(alphas) + betas*timep + (alphas/betas * >>>>>> (1-exp(betas*timep))))) >>>>>> } >>>>>> >>>>>> ### Now I thought I could obtain a matrix of the >>>>> >>>>> log-likelihood surface >>>>> >>>>> >>>>>> ### by specifying possible values for alpha and beta with the given >>>>>> data. >>>>>> ### I was able to produce this matrix with two for-loops. >>>>> >>>>> But I thought >>>>> >>>>> >>>>>> ### I could use also 'outer' in this case. >>>>>> ### This is what I tried: >>>>>> >>>>>> possible.alphas <- seq(from=0.05, to=0.15, length=30) >>>>>> possible.betas <- seq(from=0.05, to=0.15, length=30) >>>>>> >>>>>> outer(X=possible.alphas, Y=possible.betas, FUN=loggomp, >>>>> >>>>> timep=lifetimes) >>>>> >>>>> >>>>>> ### But the result is: >>>>>> >>>>>> >>>>>>> outer(X=possible.alphas, Y=possible.betas, FUN=loggomp, >>>>>> >>>>>> timep=lifetimes) >>>>>> Error in outer(X = possible.alphas, Y = possible.betas, FUN >>>>> >>>>> = loggomp, >>>>> >>>>> >>>>>> : >>>>>> dim<- : dims [product 900] do not match the length >>>>> >>>>> of object [1] >>>>> >>>>> >>>>>> In addition: Warning messages: >>>>>> ... >>>>>> >>>>>> ### Can somebody give me some hint where the problem is? >>>>>> ### I checked my definition of 'loggomp' but I thought this >>>>> >>>>> looks fine: >>>>> >>>>> >>>>>> loggomp(alphas=possible.alphas[1], betas=possible.betas[1], >>>>>> timep=lifetimes) >>>>>> loggomp(alphas=possible.alphas[4], betas=possible.betas[10], >>>>>> timep=lifetimes) >>>>>> loggomp(alphas=possible.alphas[3], betas=possible.betas[11], >>>>>> timep=lifetimes) >>>>>> >>>>>> >>>>>> ### I'd appreciate any kind of advice. >>>>>> ### Thanks a lot in advance. >>>>>> ### Roland >>>>>> >>>>>> >>>>>> +++++ >>>>>> This mail has been sent through the MPI for Demographic >>>>> >>>>> Rese...{{dropped}} >>>>> >>>>> >>>>>> ______________________________________________ >>>>>> R-help@stat.math.ethz.ch mailing list >>>>>> https://stat.ethz.ch/mailman/listinfo/r-help >>>>>> PLEASE do read the posting guide! >>>>> >>>>> http://www.R-project.org/posting-guide.html >>>>> >>>>> Thomas Lumley Assoc. Professor, Biostatistics >>>>> [EMAIL PROTECTED] University of Washington, Seattle >>>>> >>>> >>>> >>>> +++++ >>>> This mail has been sent through the MPI for Demographic Research. Should >>>> you receive a mail that is apparently from a MPI user without this text >>>> displayed, then the address has most likely been faked. If you are >>>> uncertain about the validity of this message, please check the mail header >>>> or ask your system administrator for assistance. >>>> >>>> >>> >>> ______________________________________________ >>> R-help@stat.math.ethz.ch mailing list >>> https://stat.ethz.ch/mailman/listinfo/r-help >>> PLEASE do read the posting guide! >>> http://www.R-project.org/posting-guide.html >>> >> >> >> ______________________________________________ >> R-devel@r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel > > -- > Jonathan Rougier Science Laboratories > Department of Mathematical Sciences South Road > University of Durham Durham DH1 3LE > tel: +44 (0)191 334 3111, fax: +44 (0)191 334 3051 > http://www.maths.dur.ac.uk/stats/people/jcr/jcr.html > > ______________________________________________ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > Thomas Lumley Assoc. Professor, Biostatistics [EMAIL PROTECTED] University of Washington, Seattle ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel