
An integer formula for Fibonacci numbers - 0xmohit
http://paulhankin.github.io/Fibonacci/
======
apricot
Nice. When I was a teenage self-taught programmer, an article like this one,
but about the superiority of quicksort to insertion sort, was the trigger that
got me to understand that thinking mathematically about algorithms could lead
us to a kind of understanding that transcended mere coding (although I
couldn't have put it in those words at that time). It was quite an epiphany.

I can imagine, today, a young enthusiast having learned Python and maybe done
a few Project Euler exercises, stumbling upon that post and being amazed that
you could generate Fibonacci numbers that way, and thinking that maybe there
is something interesting about that "generating functions" thing.

If that's you reading this, it's dangerous to go alone. Take this:
[https://www.math.upenn.edu/~wilf/DownldGF.html](https://www.math.upenn.edu/~wilf/DownldGF.html)

~~~
madcaptenor
And then after Wilf, read Flajolet and Sedgewick:
[http://algo.inria.fr/flajolet/Publications/book.pdf](http://algo.inria.fr/flajolet/Publications/book.pdf)

------
jordigh
Here is another method I wrote where you compute in the Q[√5] field. It can be
modified to work over Z[√5] as well:

[http://ideone.com/NWQe38](http://ideone.com/NWQe38)

~~~
xyzzyz
I implemented the same in Haskell a while ago:
[https://github.com/xyzzyz/FibBinet/blob/master/FibBinet.hs](https://github.com/xyzzyz/FibBinet/blob/master/FibBinet.hs)

With yours, both make interesting comparison of how similar problem is solved
in different languages.

~~~
eru
Why did you define both negate and (-)?

~~~
xyzzyz
I don't know. I probably shouldn't have. I accept pull requests.

------
monochromatic

        def fib(n):
            return (4 << n*(3+n)) // ((4 << 2*n) - (2 << n) - 1) & ((2 << n) - 1)
    

Looks like there's a small bug in this code.

fib(0) = 0

fib(1) = 1

fib(2) = 2

fib(3) = 3

fib(4) = 5

etc.

But there should be two values at the beginning that evaluate to 1. (Whether
it's fib(0) and fib(1), vs. fib(1) and fib(2) is just a matter of convention.
But there should definitely be two of them.)

~~~
dsp1234
A couple of commenters have mentioned this, but with his definition of fib
that's given right below in the 'overview' section, the function works:

    
    
      Fib(0) = 1
      Fib(1) = 1
      Fib(n) = Fib(n−1) + Fib(n−2)
    

So n has a constraint of n > 1, for which the function works.

------
mechagodzilla
Another obscure way to generate the fibonacci sequence - Compute the fibonacci
sequence on a hand-cranked mechanical computer:
[http://www.chrisfenton.com/the-turbo-
entabulator/](http://www.chrisfenton.com/the-turbo-entabulator/)

------
user2994cb
Nice. A cut down version using base-10:

    
    
      X = 10**3
      print X**16//(X*X-X-1)
      # 1001002003005008013021034055089144233377610
    

It's like a sideways addition version of the standard Haskell lazy list
version:

    
    
      fib = 0 : 1 : zipWith (+) fib (tail fib)

------
gfody
n*(3+n) on the right side of a left shift, you're only moving the iteration
into whatever big number library is executing that monster division

~~~
blazespin
Yep, he explains that already in the post.

------
ilzmastr
Nice post.

I never really thought about evaluating a z-transform at a particular value,
so I tied together some of the various solutions with derivations and greater
generality here:

[http://bit.ly/1WQ0Zkn](http://bit.ly/1WQ0Zkn)

------
cohomologo
He says that this is an inefficient way to generate the nth Fibonacci number,
but since it actually gives you the first n Fibonacci numbers, thats not the
fairest comparison. (Especially since the fastest methods for finding the nth
Fibonacci number don't generate all the intermediates.) Just for curiosity
sake, how does using this formula to generate all of the first n Fibonacci
numbers compare to other ways of doing that?

(You get all n with the same formula by replacing the mod 2^(n+1) (or reading
the last n+1 bits) by splitting the whole integer that is generated into n+1
bit chunks.

------
oli5679
The difference equation approach (computationally fastest) can be used to
derive a elegant closed form solution that relates to the golden ratio.

Fn=(1+√5)^n−(1−√5)^n\2^n√5

This deravation is pretty accessable and if you want to show off in code tests
:)

[http://www.cut-the-knot.org/proofs/BinetFormula.shtml](http://www.cut-the-
knot.org/proofs/BinetFormula.shtml)

~~~
agf
That's given early in the article, but requires arbitrary precision
arithmetic:

Another method is to find a closed form for the solution of the recurrence
relation. This leads to the real-valued formula: Fib(n)=(ϕn+1−ψn+1)/5‾√) where
ϕ=(1+5‾√)/2 and ψ=(1−5‾√)/2\. The practical flaw in this method is that it
requires arbitrary precision real-valued arithmetic, but it works for small n.

~~~
Someone
If you add a "round to integer" step at the end, it doesn't require arbitrary
precision arithmetic. Careful numerical analysis can tell you how many digits
of precision you need to compute fib(n).

I would guess the end result would be similar to that of this method (2n bits
being more than sufficient), the difference being that this method puts all
the digits before the decimal point.

Also, for large n, you may be able to assume ψ = 0 to speed up computations
(given ψ < n, its nth power will get vanishingly small)

But the matrix method is the easiest fast method one can write and prove
robust.

(It is not fastest because the trivial binary approach doesn't product optimal
addition chains. See
[https://en.wikipedia.org/wiki/Addition_chain](https://en.wikipedia.org/wiki/Addition_chain)
or (dense writing, as is normal in HAKMEM)
[http://www.inwap.com/pdp10/hbaker/hakmem/recurrence.html](http://www.inwap.com/pdp10/hbaker/hakmem/recurrence.html))

Also, there is a very simple method for implementing "isFib":

    
    
      isFib(n) := isSquare(5n^2+4) or isSquare(5n^2-4)

~~~
user2994cb
Most fast methods for computing fib(n) come down to some variation of repeated
squaring, so the time is dominated by the last multiplication (since the
number of digits is doubling each time).

------
noobermin
Nice! Next time I have a job interview, I'll look this up the night before and
confound the interviewer when it works!

~~~
alain_gilbert
I like this one as well:

    
    
        Fibonacci(n) = (Φ^n - (1-Φ)^n) / √5
        (Where Φ = (1 + √5) / 2)

~~~
tanderson92
Mathematically they might be the same, but they reduce to different problems
in computer science. The OP uses algorithmic approaches, but yours requires
finite-precision root solvers (for the calculation of \Phi ) and some
numerical analysis to determine how many bits of \sqrt(5) are needed to be
correct to yield a calculation of Fibonacci(n) which is correct to the nearest
integer.

~~~
panic
You don't need to use a root solver. If you represent numbers as "a + b
sqrt(5)" you can do algebra directly in that space.

~~~
tanderson92
I take it you are making a joke? Heh.

Otherwise, I'd point out that any result where you ultimately need to use
Fibonacci(n) as an actual integer, you can't represent it as an algebraic
combination of "sqrt(5)".

~~~
panic
No joke! See this thread:
[https://news.ycombinator.com/item?id=11561336](https://news.ycombinator.com/item?id=11561336)
for some real-life implementations of this technique. Since the Fibonacci
numbers are integers, at the end of your computation you'll get a number like
"a + 0 sqrt(5)". Then you can just take the "a" part.

~~~
tanderson92
Ah! I see what you're saying. Thank for the link, that is a clever approach.

------
roywiggins
My recollection is that the closed formula (with phi) is derived from the
generating function as well, though the derivation was nigh miraculous when I
saw it done.

~~~
cousin_it
It's not miraculous at all, and doesn't need to involve generating functions
:-)

Consider all sequences f(n) that fit the constraint f(n) + f(n+1) = f(n+2),
with arbitrary initial values. Such sequences form a vector space, because
adding them together or multiplying by a constant doesn't break the
constraint. That vector space is two-dimensional, because the two initial
values determine the rest of the sequence. Now we just need to find two
different sequences that form a basis of that space. All other sequences can
be expressed as linear combinations of these two.

How do we find the two basis sequences? Let's make a lucky guess that they are
geometric progressions with some constant c. Then we have c^n + c^(n+1) =
c^(n+2), or equivalently 1 + c = c^2. That equation has two solutions, phi
(the golden ratio, about 1.618) and psi = -1/phi.

Going back to the original problem, we need to express the usual Fibonacci
sequence (which starts with 1,1) as a linear combination of the sequences
phi^n and psi^n. We just need to match the two initial values by picking the
right coefficients, which turn out to be 1/sqrt(5) and -1/sqrt(5), giving you
the desired closed form formula.

The above approach generalizes to any recurrence of the form a * f(n) + b *
f(n+1) + c * f(n+2) + ... = f(n+k). All such sequences will form a
k-dimensional vector space, and you can find k different geometric
progressions by solving a polynomial equation of degree k which has k roots.
All other solutions will be linear combinations of these geometric
progressions. (There will be complications if some roots coincide, but it can
be worked out.)

To me the whole chain of reasoning feels very natural and almost inevitable.
If I didn't know anything about Fibonacci numbers but had a good grasp of
popular math, that's how I would approach the problem right away. Does that
make sense?

~~~
roywiggins
It does- I remember enough from Linear Algebra that vector spaces aren't
completely foreign, which helps a lot.

I think the generating-function method[1] is a case of pulling out a powertool
(generating functions) to prove a simple thing to demonstrate the power of the
tool, whereas your explanation takes the direct route and connects more of the
threads about why it's true.

[1] found an instance here:
[http://austinrochford.com/posts/2013-11-01-generating-
functi...](http://austinrochford.com/posts/2013-11-01-generating-functions-
and-fibonacci-numbers.html)

------
recursive
Can anyone explain what's meant by this?

> Multiplying by x^(n+2) and summing over all n, we get

Is n the iterating variable, or the domain? What are the possible values of n?
Wouldn't "all" values (whichever set that may be) give an infinite sum? I
thought that infinite expressions did not obey the same laws as finite ones,
and couldn't be generally used with algebraic transformations.

I guess I don't know as much math as I thought.

~~~
MHordecki
Disclaimer: I have studied these functions a long, long time ago. I barely
remember anything.

In that particular point in the article, n is both. It is a natural number
that is the domain of Fib, and the iterating variable of the generating
function. As you've noticed, the sum is indeed infinite - this does not
matter, however, as at no point is the actual sum of a generating function
series important - the whole series mechanism is just a nice conduit to reason
about the coefficients (subsequent values of Fib, in this case) using more
familiar and developed mathematics for infinite series (divergent or not).

I remember being fascinated by generating functions in college. I viewed them
as sort of a beautiful hack in how to tie various combinatorial structures to
the more ordinary algebraic operations. This mini-field is called enumerative
combinatorics. The only part of discrete mathematics that I've actually
enjoyed :)

------
deproders
Great! Somehow reminds me the Bailey–Borwein–Plouffe formula for computing the
nth PI digit
[https://en.wikipedia.org/wiki/Bailey%E2%80%93Borwein%E2%80%9...](https://en.wikipedia.org/wiki/Bailey%E2%80%93Borwein%E2%80%93Plouffe_formula)

------
mijoharas
Is anyone able to show how you get from this line:

ΣnFib(n+2)x^(n+2)=ΣnFib(n+1)x^(n+2)+ΣnFib(n)x^(n+2)

to this one:

F(x)−x−1=x(F(x)−1)+x2F(x)

I haven't managed to figure it out and have a couple of colleagues that
haven't been able to work it out as well.

~~~
a1k0n
ΣnFib(n+2)x^(n+2) is F(x)−x−1 because it's an infinite series of powers of x,
except since it's x^(n+2) then x^1 (x) and x^0 (1) never appear, so you need
to subtract them from F(x) which is ΣnFib(n)x^n. I hope that's clear and
explains the rest.

------
karcass
Hmm, I think there's an edge-condition bug. Starting with fib(0), its values
are (0,1,2,3,5,8...) instead of (1,1,2,3,5,8...).

~~~
catnaroek
1 must all appear twice in the sequence. Otherwise I agree: it ought to begin
at 0.

------
Houshalter
The Lucas numbers are more interesting. Instead of starting with 1, 1, which
is kind of arbitrary, start with 2, 1. The resulting sequence is exactly
round(phi^n). Which is a much stronger link to the golden ratio. And is found
just as often in nature.

------
PaulHoule
It's nice to see something about the fibo numbers that has some real math in
it, as opposed to the articles that make it big in proggit everyday that
functional programming fanboys think are cool but that really discredit FP in
the eyes of everybody else.

