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.

Reply via email to