This solves the problem.
fibs = function() { fibNumbers = 0:1 fib = function(n) { print(n) n[n<1] <- 1 cat("again: ", n, fill=TRUE) ifelse(n <= length(fibNumbers), fibNumbers[n], fibNumbers[n] <- fib(n-1) + fib(n-2)) } } >x <- fibs() >x(5:7) [1] 5 6 7 again: 5 6 7 [1] 4 5 6 again: 4 5 6 [1] 3 4 5 again: 3 4 5 [1] 2 3 4 again: 2 3 4 [1] 1 2 3 again: 1 2 3 [1] 0 1 2 again: 1 1 2 [1] -1 0 1 again: 1 1 1 [1] 0 1 2 again: 1 1 2 [1] 1 2 3 again: 1 2 3 [1] 0 1 2 again: 1 1 2 [1] -1 0 1 again: 1 1 1 [1] 2 3 4 again: 2 3 4 [1] 1 2 3 again: 1 2 3 [1] 0 1 2 again: 1 1 2 [1] -1 0 1 again: 1 1 1 [1] 0 1 2 again: 1 1 2 [1] 3 4 5 again: 3 4 5 [1] 2 3 4 again: 2 3 4 [1] 1 2 3 again: 1 2 3 [1] 0 1 2 again: 1 1 2 [1] -1 0 1 again: 1 1 1 [1] 0 1 2 again: 1 1 2 [1] 1 2 3 again: 1 2 3 [1] 0 1 2 again: 1 1 2 [1] -1 0 1 again: 1 1 1 [1] 3 5 8 *-- Russ Abbott* *_____________________________________________* *** Professor, Computer Science* * California State University, Los Angeles* * Google voice: 747-*999-5105 * blog: *http://russabbott.blogspot.com/ vita: http://sites.google.com/site/russabbott/ *_____________________________________________* On Sat, Apr 9, 2011 at 10:51 AM, Russ Abbott <russ.abb...@gmail.com> wrote: > I attempted to vectorize the preceding as follows. > > > fibs = function() { > fibNumbers = 0:1 > fib = > function(n) { > print(n) > ifelse(n <= length(fibNumbers), > fibNumbers[n], > fibNumbers[n] <- fib(n-1) + fib(n-2)) > } > } > > Unless I'm misunderstanding what's going on,* ifelse()* seems to compute > the conditional on the entire vector and take an *&* of the result. Here > is the output. (Note the print statement at the beginning of the function.) > > >x(5:7)[1] 5 6 7 > [1] 4 5 6 > [1] 3 4 5 > [1] 2 3 4 > [1] 1 2 3 > [1] 0 1 2 > [1] -1 0 1Error in fibNumbers[n] : only 0's may be mixed with negative > subscripts > > > *-- Russ Abbott* > *_____________________________________________* > *** Professor, Computer Science* > * California State University, Los Angeles* > > * Google voice: 747-*999-5105 > * blog: *http://russabbott.blogspot.com/ > vita: http://sites.google.com/site/russabbott/ > *_____________________________________________* > > > > On Sat, Apr 9, 2011 at 12:50 AM, Russ Abbott <russ.abb...@gmail.com>wrote: > >> The following doesn't rely on lazy evaluation, but it accomplishes >> something similar by taking advantage of R's closure capability. >> >> >fibs = function() { >> fibNumbers = 0:1 >> fib = function(n) { >> if (n <= length(fibNumbers)) return(fibNumbers[n]) >> fibNumbers[n] <- fib(n-1) + fib(n-2) >> return(fibNumbers[n]) >> } >> } >> >x = fibs() >> >x(1) >> [1] 0 >> >x(2) >> [1] 1 >> >x(7) >> [1] 8 >> >> The recursive calls to fib(n-1) and fib(n-2) are not inefficient since >> most of the results will be returned via lookup in fibNumbers. This also >> works. >> >> >sapply(1:12, x) [1] 0 1 1 2 3 5 8 13 21 34 55 89 >> >> >> *-- Russ * >> >> >> >> On Fri, Apr 8, 2011 at 8:36 PM, Russ Abbott <russ.abb...@gmail.com>wrote: >> >>> Here's how to do it in Haskell. >>> >>> First define fibs to be an infinite list. Since Haskell is lazy, the list >>> isn't actually created until needed. >>> >>> The function zipWith takes three arguments: a function and two lists. (It >>> is similar to sapply except that it takes a function and two lists.) It >>> applies the function to the two lists pairwise (as in R) and returns the >>> result. In R one would presumably write this fibs + (tail fibs). >>> >>> So zipWith (+) fibs (tail fibs) adds the lists fibs and (tail fibs). >>> >>> So fibs is defined to be [0, 1, followed by the result of zipWith ... ]. >>> >>> >>> let fibs = 0 : 1 : (zipWith (+) fibs (tail fibs)) >>> fibs :: (Num a) => [a] >>> (0.00 secs, 527804 bytes) >>> >>> The previous statement defined fibs, which is an infinite list. The next >>> statement returns the first 10 element. >>> >>> >>> > take 10 fibs >>> [0,1,1,2,3,5,8,13,21,34] >>> >>> In R, one might try the following. >>> >>> >fibs <- c(0, 1, (fibs + fibs[-1])) >>> >>> Error: object 'fibs' not found >>> >>> But since this is a recursive definition in a context in which recursion is >>> not expected, an error message is produced. >>> *-- Russ * >>> >>> >>> On Fri, Apr 8, 2011 at 12:51 AM, peter dalgaard <pda...@gmail.com>wrote: >>> >>>> >>>> On Apr 8, 2011, at 06:08 , Russ Abbott wrote: >>>> >>>> > Haskell is the prototypical lazy evaluation language. One can compute >>>> a >>>> > Fibonacci sequence by the Haaskell equivalent of the following R code. >>>> > >>>> >> fibs <- c(0, 1, rep(0, 8)) >>>> >> fibs[3:10] <- fibs + fibs[-1] >>>> > >>>> > This works as follows. >>>> > >>>> > fibs = 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 >>>> > fibs = 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 >>>> > >>>> > When one adds fibs to fibs[-1], one is effectively adding diagonally: >>>> > fibs[3] <- fibs[1] + fibs[2] >>>> > fibs[4] <- fibs[2] + fibs[3] >>>> > fibs[5] <- fibs[3] + fibs[4] >>>> > etc. >>>> > >>>> > In Haskell, the value of fibs[3] used to compute fibs[4] is the value >>>> just >>>> > created by adding fibs[1] and fibs[2]. Similarly the value of fibs[4] >>>> used >>>> > to compute fibs[5] is the value that was just created in the previous >>>> > addition. In other words: >>>> > >>>> > fibs[3] <- fibs[1] + fibs[2] # 0 + 1 = 1 >>>> > fibs[4] <- fibs[2] + fibs[3] # 1 + 1 = 2 >>>> > fibs[5] <- fibs[3] + fibs[4] # 1 + 2 = 3 >>>> > fibs[6] <- fibs[4] + fibs[5] # 2 + 3 = 5 >>>> > etc. >>>> > >>>> > >>>> > But if you actually carry out this calculation in R, this is you get. >>>> > >>>> >> v <- c(0, 1, rep(0, 8)) >>>> > >>>> >> v >>>> > >>>> > [1] 0 1 0 0 0 0 0 0 0 0 >>>> > >>>> >> v[3:10] <- v + v[-1] >>>> > >>>> > Warning messages: >>>> > >>>> > 1: In v + v[-1] : >>>> > >>>> > longer object length is not a multiple of shorter object length >>>> > >>>> > 2: In v[3:10] <- v + v[-1] : >>>> > >>>> > number of items to replace is not a multiple of replacement length >>>> > >>>> >> v >>>> > >>>> > [1] 0 1 1 1 0 0 0 0 0 0 >>>> > >>>> > >>>> > Is there any way to make this work? >>>> > >>>> >>>> I should hope not.... (it would break call-by-value semantics, for one >>>> thing) >>>> >>>> The closest you can get is something like >>>> >>>> > delayedAssign("fib6", fib5+fib4) >>>> > delayedAssign("fib5", fib4+fib3) >>>> > delayedAssign("fib4", fib3+fib2) >>>> > delayedAssign("fib3", fib2+fib1) >>>> > delayedAssign("fib2", 1) >>>> > delayedAssign("fib1", 0) >>>> > fib6 >>>> [1] 5 >>>> >>>> (you can construct those assignments programmatically in a loop with a >>>> little extra work.) >>>> >>>> -- >>>> Peter Dalgaard >>>> Center for Statistics, Copenhagen Business School >>>> Solbjerg Plads 3, 2000 Frederiksberg, Denmark >>>> Phone: (+45)38153501 >>>> Email: pd....@cbs.dk Priv: pda...@gmail.com >>>> >>>> >>> >> > [[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.