If you're computing Fibonacci numbers using only addition, no matter how clever your recursion, you will always lose out to algorithms that use multiplication. https://www.nayuki.io/page/fast-fibonacci-algorithms
Exactly. And fibonacci numbers also have a closed form which can be (in theory) evaluated in O(1): http://austinrochford.com/posts/2013-11-01-generating-functi...
Tail Recursion Tactics: Fibonacci
31–38 of 38 posts
Re: Tail Recursion Tactics: Fibonacci
#32Tail call optimization is a clever, but even in functional languages, twisting your code around to use tail calls is often a code smell. Most uses of tail recursion would be better-served by using some higher-order functions. The reason is that when you write something tail recursively, it's sort of like rolling your own iteration. This is particularly true because many platforms don't supply tail call optimization,…
def fib(n):
a, b = 0, 1
for _ in range(n):
a, b = b, a + b
return b
No itertools, not overly complex, no tail recursion.If you were careful of the scoping rules something like foo(get_next(i) for i in whatever()) could be made to work without too much trouble (also without itertools) if you needed a sequence. Probably just throw a lambda in there instead of get_next and python would be happy, too lazy to work it out.
[0]http://www.koderdojo.com/blog/python-fibonacci-number-genera...
--edit--
Actually, I think this function gives the wrong result for 0 and maybe 1, just copypasta'd the code so blame them...
Re: Tail Recursion Tactics: Fibonacci
#33Tail call optimization is a clever, but even in functional languages, twisting your code around to use tail calls is often a code smell. Most uses of tail recursion would be better-served by using some higher-order functions. The reason is that when you write something tail recursively, it's sort of like rolling your own iteration. This is particularly true because many platforms don't supply tail call optimization,…
Poked around on the google[0]: def fib(n): a, b = 0, 1 for _ in range(n): a, b = b, a + b return b No itertools, not overly complex, no tail recursion. If you were careful of the scoping rules something like foo(get_next(i) for i in whatever()) could be made to work without too much trouble (also without itertools) if you needed a sequence. Probably just throw a lambda in there instead of get_next and python would be…
EDIT: Also c'mon man. This is not a problem that you need to Google. :P
Re: Tail Recursion Tactics: Fibonacci
#34If you're computing Fibonacci numbers using only addition, no matter how clever your recursion, you will always lose out to algorithms that use multiplication. https://www.nayuki.io/page/fast-fibonacci-algorithms
Re: Tail Recursion Tactics: Fibonacci
#35https://wiki.haskell.org/The_Fibonacci_sequence
https://www.willamette.edu/~fruehr/haskell/evolution.html
;-)
But, thanks for the pointer - from a glance it looks like a fine way to compare and contrast approaches/flavours of haskell programming.
Re: Tail Recursion Tactics: Fibonacci
#36I love your explanation of how to arrive at the vector transformation function. You might enjoy reading an article I wrote a few years ago that touches on maxtrix/vector computation of linear recurrences: http://aperiodical.com/2014/06/discovering-integer-sequences... Not as detailed as your post though. Thanks for a great write up!
Re: Tail Recursion Tactics: Fibonacci
#37Earlier quoted context omitted.
Exactly. And fibonacci numbers also have a closed form which can be (in theory) evaluated in O(1): http://austinrochford.com/posts/2013-11-01-generating-functi...
The number of digits in the nth Fibonacci number grows linearly with n, so you can't compute these digits in O(1). The fastest algorithms, described in the link I gave, have complexity O(n * something) where "something" grows much slower than n and depends on the bigint multiplication algorithm used.
Re: Tail Recursion Tactics: Fibonacci
#38Earlier quoted context omitted.
The number of digits in the nth Fibonacci number grows linearly with n, so you can't compute these digits in O(1). The fastest algorithms, described in the link I gave, have complexity O(n * something) where "something" grows much slower than n and depends on the bigint multiplication algorithm used.
The matrix exponentiation algorithm in the link you sent is O(log(n)). Yes, this might seem strange because the output (F_n) itself has n bits. But in practice most of the implementations would use long integers for output, so log(F_n) < 64 for these implementations.