nvec ← ##.fibonacci num ⍝ Tail-recursive Fibonacci. ⍝ Leonardo Fibonacci 1170-1250. An illustration of tail recursion with a left argument accumulator: fibonacci←{ ⍝ Tail-recursive Fibonacci. ⍺←0 1 ⍵=0:⍬⍴⍺ (1↓⍺,+/⍺)∇ ⍵-1 } Compare this coding with the naïve stack-recursive version: fib←{ ⍵∊0 1:⍵ +/∇¨⍵-1 2 } Some alternatives: Nick Nikolov and Jay Foad suggest: fib ← {⊃(+/,⊃)⍣⍵⊢1} and: fib ← +.!∘⌽⍨⍳ ⍝ ⎕io←0 John R. Clark suggests these non-recursive functions: fib ← {+/{⍵!⌽⍵}(⍳⍵)-⎕io} ⍝ JRC[1] and fib ← {1↓⍎((3×⍵)⍴'⌽+\'),'1 0'} ⍝ JRC[2] JRC[1] may be cast as a derived function, using monadic commute: fib ← +/∘(!∘⌽⍨)∘(-∘⎕io)∘⍳ ⍝ see →tacit← and JRC[2] may be converted to use the primitive power operator: fib ← {⍬⍴⌽∘(+\)⍣⍵,0 1} ⍝ ⍣ is primitive power operator. or the equivalent derived function, using reduction for power (see →pow←): fib ← ⍬∘⍴∘⊃∘(⊢∘⌽∘(+\)/)∘(,∘(⊂0 1))∘⍳ In a similar way, power can be applied on the following matrix multiplication: |1 1| |A B| |A+C B+D| |1 0| × |C D| = | A B | to obtain a terse but costly fib function: fib ← {⊃(+.×⍣⍵)⍨2 2⍴1 1 1 0} Another simple way is to perform a "hidden scan" with a reduction (see →scan←): fib ← {⊃{⍵,+/¯2↑⍵}/⍵⍴1} The following function illustrates the relationship between the Fibonacci sequ- ence and rational approximations to the "golden mean" (Phi). See →phinary←. fib←{1∧+∘÷/0,⍵/1} │ │ └───── continued fraction: 0 1 1 1 ... │ └───────── approximation to Phi-1: 0 1 0.5 0.666 ... └─────────── numerator of rational: 0 1 1 2 3 5 8 13 21 34 ... Dick Bowman reminds us of Binet's formula, which also uses Phi: fib ← {((phi*⍵)-(1-phi←.5×1+5*.5)*⍵)÷5*.5} Peter-Michael Hager suggests this pleasantly symmetrical coding of Binet's form- ula: fib←{ p←0.5×1+5*0.5 q←0.5×1-5*0.5 ((p*⍵)-q*⍵)÷p-q } In the above, constants p and q could be pre-evaluated and bound as the left and right operands of a dyadic operator: fib ← (0.5×1+5*0.5) {((⍺⍺*⍵)-⍵⍵*⍵)÷⍺⍺-⍵⍵} (0.5×1-5*0.5) or: fib ← (0.5×1+1 ¯1×5*0.5)∘{(-⌿⍺∘.*⍵)÷-/⍺} As Binet's formula employs only scalar functions, it may be applied to an array argument. Using the above definition: fib (0 1 2)(2 2⍴2+⍳4) ┌─────┬───┐ │0 1 1│2 3│ │ │5 8│ └─────┴───┘ Jane Sullivan extends Binet's formula to the real and complex domains. A D-cod- ind of Jane's real-valued function might look like this: fib←{ ⍝ Sullivan z←0.5×1+s←5*0.5 ((z*⍵)-(2○○⍵)×z*-⍵)÷s } Ref: Sullivan J. "Functional Extensions to the Fibonacci Sequence", Vector 15.4. Note that Jane's function is defined for negative arguments: ⎕pp←3 ⋄ fib ¯5 ¯4.5 to 5 ⍝ fib ¯5 ¯4.5 .. 5 5 0.0513 ¯3 0.083 2 0.134 ¯1 0.217 1 0.352 0 0.569 1 0.92 1 1.49 2 2.41 3 3.9 5 Veli-Matti Jantunen suggests this coding for large Fibonacci numbers, eg >10000. fib←{⎕ml←3 ⍵≤2:1 {(+/∧\⍵='0')↓⍵ },'ZI9'⎕fmt(⍵-2){ ⍺>0:(⍺-1)∇(↑⌽⍵)({ ∧/⍵<1e9:⍵ ⋄ (1e9|⍵)+1⌽⍵≥1e9 }(↑⍵)+↑⌽⍵) ⋄ ↑⌽⍵ }2⍴⊂(-⌈⍵÷40)↑1 } Paul Mansour offers this function, which uses OO techniques: Fibonacci←{⎕io←0 ⍝ First ⍵ fibonacci numbers. s←⎕NS'' ⍝ Class s.(f←{⍺←⎕THIS ⋄ ⍺.i<2:⍺.n ⋄ ⊢⍺.n←+/⍺.a[⍺.i-1+⍳2].n}) ⍝ Method v←⎕NS¨⍵⍴s ⍝ Collection v.i←⍳⍵ ⍝ Item number v.n←⍵↑0 1 ⍝ Initialize v.a←⊂v ⍝ Each knows all v.b←(1+⍳⍵)⍴¨⊂v ⍝ Each knows self and previous? v.f 0 ⍝ Compute } And finally: "That joke about the Fibonacci sequence was worse than the last two jokes put together" - JD Lucas numbers ------------- Initialising the recursion with 2 1, instead of 0 1, returns the Lucas sequence: 2 1∘fibonacci¨ 0 to 20 ⍝ François Lucas 1842-1891. 2 1 3 4 7 11 18 29 47 76 123 199 322 521 843 1364 2207 3571 5778 9349 15127 http://en.wikipedia.org/wiki/Lucas_number Fibonacci-based number system ----------------------------- The Fibonacci sequence may be used as the base of a number system: fibcode←{ ⍝ fibonacci-coding of number ⍵. pair←{ ⍝ fib-pair n←+/⍵ ⍝ next term. ⍺<n:⍵ ⍝ term large enough: finished. ⍺ ∇ 1↓⍵,n ⍝ next pair } ⍝ :: i j ← n ∇ i j vec←{ ⍝ ⍺ is accumulator. n(i j)←⍵ ⍝ remaining number and current fib pair. i=0:⍺,1 ⍝ exhausted radix list: accumulator, sentinel. f←(j-i),i ⍝ next fib pair. t←n≥j ⍝ next term and r←n-t×j ⍝ remainder. (t,⍺)∇ r f ⍝ accumulated fib-coding. } ⍝ :: [b] ← [b] ∇ n(i j) ⍬ vec ⍵,⊂⍵ pair 0 1 ⍝ fi } ↑⍕∘fibcode¨0 to 10 ⍝ fibonacci coding of 0..10 1 1 1 0 1 1 0 0 1 1 1 0 1 1 0 0 0 1 1 1 0 0 1 1 0 1 0 1 1 0 0 0 0 1 1 1 0 0 0 1 1 0 1 0 0 1 1 See: http://en.wikipedia.org/wiki/Fibonacci_coding Example: fibonacci¨⍳10 ⍝ ⎕io=1: F1 .. F10 1 1 2 3 5 8 13 21 34 55 fibonacci¨ 0 to 9 ⍝ first 10 Fibonacci numbers: F0 ..F9. 0 1 1 2 3 5 8 13 21 34 ⍝ compare monitor of tail-recursive version: fibonacci mdf 20 0 fibonacci←{ ⍝ Tail-recursive Fibonacci. 21 ⍺←0 1 21 ⍵=0:⍬⍴⍺ 20 (1↓⍺,+/⍺)∇ ⍵-1 0 } ⍝ ... with monitor of stack-recursive version: fib mdf 20 0 fib←{ 21891 ⍵∊0 1:⍵ 10945 +/∇¨⍵-1 2 0 } See also: factorial mdf pow to cfract tacit nats See also: phinary ratrep ratsum Back to: contents Back to: Workspaces