|
36. Fibonacci Numbers The n-th element of the sequence 0 1 1 2 3 5 8 13 21 34 55 can be computed in a variety of ways: Double Recursion
fib←{1≥⍵:⍵ ⋄ (∇⍵-2)+∇⍵-1}
fib¨ ⍳10
0 1 1 2 3 5 8 13 21 34
Like other multiple recursions, this function can be made more efficient by use of the memo operator: fib M¨ ⍳10 0 1 1 2 3 5 8 13 21 34 cmpx 'fib 30' 'fib M 30' fib 30 → 1.44E0 | 0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕ fib M 30 → 1.50E¯3 | -100% Single Recursion
fib1←{⍺←0 1 ⋄ 0=⍵:⊃⍺ ⋄ (1↓⍺,+/⍺)∇⍵-1}
fib1¨ ⍳10
0 1 1 2 3 5 8 13 21 34
Iteration
fib2←{⊃+\∘⌽⍣⍵⍳2}
fib2¨ ⍳10
0 1 1 2 3 5 8 13 21 34
Power of Phi Power of the golden ratio φ (2÷⍨1+5*0.5). Because of the limited precision of 64-bit IEEE floating-point numbers this method is good only for n up to 70.
fib3←{⌊0.5+r÷⍨(2÷⍨1+r←5*0.5)*⍵}
fib3¨ ⍳10
0 1 1 2 3 5 8 13 21 34
Continued Fractions
fib4←{1∧+∘÷/0,⍵⍴1}
fib4¨ ⍳10
0 1 1 2 3 5 8 13 21 34
Sum of Binomial Coefficients fib5← ⍳ +.! ⌽∘⍳ fib5¨ ⍳10 0 1 1 2 3 5 8 13 21 34 Matrix Powers The recurrence relation for the Fibonacci numbers can be written in matrix form:
The n-th power of the matrix 2 2⍴0 1 1 1 obtains by repeated squaring and hence can be done in O(⍟n) steps.
powop←{⍺←⊣ ⋄ ⍺∘⍺⍺{⍺⍺⍣⍵⊢⍵⍵}⍵¨⍵⍵}
fib6←{0 1⌷⊃+.×/+.×⍨powop(⍸⌽2⊥⍣¯1⊢⍵)∘.∨⍨⍳2}
fib6¨ 1↓⍳10
1 1 2 3 5 8 13 21 34
fib6 does not work for 0 . If APL were extended so that:
fib6a←{0 1⌷⊃+.×/+.×⍨⍣(⍸⌽⊤⍵)∘.∨⍨⍳2}
Because of the limited precision of 64-bit IEEE floating-point numbers this method is good only for n up to 78. But the algorithm is valid for extended precision integers. In J:
fib6 800
692830818642247171362900776813285182733991243852048207189660
405976914355872783831122771619675325306753741708574047
43017623467220361778016172106855838975759985190398725
Binet’s Formula
Binet’s formula derives by solving for the roots of the characteristic polynomial (x*2)-x+1 and then finding coefficients for (fib ⍵)=(a×r0*⍵)+(b×r1*⍵) which satisfy the initial conditions. The roots are the golden ratio 2÷⍨1+5*0.5 and its negative reciprocal 2÷⍨1-5*0.5 . Therefore:
fib7←{r÷⍨-/⍵*⍨2÷⍨1+1 ¯1×r←5*0.5}
fib7¨ ⍳10
0 1 1 2 3 5 8 13 21 34
The algorithm can be implemented using integers operations without use of √5, by doing the calculations in the ring extensions Q[√5] and Z[√5]. The powers can be done by repeated squaring and therefore the algorithm is O(⍟n) . Rewrite Rules Based on a suggestion by Viktor Cerovski [104], the rewrite rules 0→1 and 1→0 1 are applied n times, starting with 0 . The sum of the resulting sequence is the n-th Fibonacci number.
fib8←{+/ ∊∘(↓∘0 1¨)∘~⍣⍵ ,0}
fib8¨ ⍳10
0 1 1 2 3 5 8 13 21 34
Appeared in
[43]
|