38

The standard way (other than generating up to $N$) is to check if $(5N^2 + 4)$ or $(5N^2 - 4)$ is a perfect square. What is the mathematical logic behind this? Also, is there any other way for checking the same?

Jeff P.
  • 206
  • 1
  • 8
Quixotic
  • 21,425
  • 30
  • 121
  • 207
  • The [Binet formula](http://mathworld.wolfram.com/BinetsFibonacciNumberFormula.html) should prove to be useful. – J. M. ain't a mathematician Nov 12 '10 at 13:21
  • @J.M :I knew Binnet formula but it's not much good when you are trying to generate up-to $10^{12}$ or more, since it will loose precision due to floating point operation, there also is one algorithm of O(lg n) time which uses matrix exponentiation trick for computing `fib(n)`, but I don't really want to generate and check. – Quixotic Nov 12 '10 at 13:27
  • @J.M:Or do you mean that I can reduce Binnet formula to something that can be used for checking ? – Quixotic Nov 12 '10 at 13:27
  • A related thread at stackoverflow: http://stackoverflow.com/questions/2432669/test-if-a-number-is-fibonacci – Martin Sleziak Sep 02 '11 at 10:41

6 Answers6

25

Binet's formula tells you that $F_n$ is asymptotic to $\frac{1}{\sqrt{5}} \phi^n$, where $\phi = \frac{1 + \sqrt{5}}{2}$ is the golden ratio. So to check if a number $x$ is a Fibonacci number you should compute $n = \frac{\log (\sqrt{5} x)}{\log \phi}$. If this number is very close to an integer then $x$ should be very close to the Fibonacci number $F_{[n]}$ where $[n]$ denotes the closest integer to $n$. In fact I think $x$ is a Fibonacci number if and only if the error is less than about $\frac{\log \phi}{5x^2}$.

But if you don't trust that computation, you can compute $F_{[n]}$ in $O(\log n)$ time, for example by using binary exponentiation to compute powers of the matrix $\left[ \begin{array}{cc} 1 & 1 \\\ 1 & 0 \end{array} \right]$, and then you can check whether this number equals $x$.

Your first question can be answered using the theory of (generalized) Pell equations.

Qiaochu Yuan
  • 359,788
  • 42
  • 777
  • 1,145
  • Well,I derivation you showed me using the Binnet's formula will be again much prone to loss of precision,so it is not a much of useful while I am writing in C-family of languages, so I guess the perfect square method is something I need to concentrate, since that will be more or less O(1) + complexity of the square root algorithm,but I don't really understand how are you deriving it from Pell equation ?! :( – Quixotic Nov 12 '10 at 13:53
  • 2
    @Debanjan: if you are working in finite precision you can still compute F_{[n]}. 5n^2 + 4 is a square if and only if the (generalized) Pell equation m^2 - 5n^2 = 4 has a solution, and similarly for 5n^2 - 4. The theory of Pell equations can be adapted to this case and will tell you that n has to be a Fibonacci number. – Qiaochu Yuan Nov 12 '10 at 14:33
  • @ Qiaochu Yuan: `if you are working in finite precision you can still compute F_{[n]}` Can you please explain how ? I am interpreting `F_{[n]}` as `Fib(floor(n))` where Fib(n) computes n-th Fibonacci number and the working of `floor` is mentioned here : http://www.cplusplus.com/reference/clibrary/cmath/floor/ – Quixotic Nov 12 '10 at 15:09
  • Also now I got how you are interpreting it from Pell equation. – Quixotic Nov 12 '10 at 15:14
  • 2
    Or we can use binary search and avoid floating point computations altogether. – Aryabhata Nov 12 '10 at 15:24
  • @Debanjan: the powers of the matrix I wrote down are Fibonacci numbers. You can compute the [n]th power (where [n] is the closest integer, not the floor) using binary exponentiation and this will tell you what F_{[n]} is. @Moron: can you elaborate? – Qiaochu Yuan Nov 12 '10 at 15:29
  • @Qiao: Guess an $n$, compute $F_n$ (using matrix powers) and compare with $N$. If the entries are smaller, we need a bigger $n$, else smaller. This might be a bit slower, but that is the price you pay for avoiding floating point computations. – Aryabhata Nov 12 '10 at 15:34
  • 1
    @Moron: I don't understand. Computing logarithms is really, really easy; you can get a good estimate just by using strlen(x) and then you've already narrowed down n to within maybe four integers. Doesn't your algorithm take something like O(log x log log x) time? Mine takes O(log log x). – Qiaochu Yuan Nov 12 '10 at 15:42
  • @QIao: Sorry I meant to say _if you want to avoid floating point computations_. With proper hardware support floating point computation are O(1). I am not claiming binary search is faster. It was mainly in response to "trusting" the results. strlen x is O(logx) btw. – Aryabhata Nov 12 '10 at 15:45
  • @QIao: How can you be sure of `n` where you are computing `n`with this formula $n = \frac{\log (\sqrt{5} x)}{\log \phi}$, I guess for $n \gt 10^{12}$or more this method will invoke wrong answers, the later part of matrix exponentiation trick is not new to me though, but I am not sure `n` can be computed precisely without invoking floating point error. – Quixotic Nov 13 '10 at 14:08
  • @Moron: Bsearch seems a good approach that will ensure not invoking floating point error! :) – Quixotic Nov 13 '10 at 14:11
  • @QIao:For the pell equation I will +1 your answer and also accept it since I was also asking for an explanation of the first approach.Thanks :) – Quixotic Nov 13 '10 at 14:13
17

HINT $\rm\ n\:$ is a Fibonacci number iff the interval $\rm\ [\phi\ n - 1/n,\ \phi\ n + 1/n]\ $ contains a positive integer (the next Fibonacci number for $\rm\ n > 1\:$). This follows from basic properties of continued fractions. For one proof see e.g. $\ $ T. Komatsu: The interval associated with a fibonacci number. $\ $ This is a reasonably efficient test since it requires only a few multiplications and additions. $\ $ For example, $\rm\ 2 \to [2.7,\ 3.7],\ \ 3\to [4.5,\ 5.2],\ \ 5 \to [7.9,\ 8.3]\ \ldots$

Bill Dubuque
  • 257,588
  • 37
  • 262
  • 861
4

As for ways to check is a number is a Fibonacci number, I'll speak to efficient testing since the other aspects seem covered. First, you should check if the residue mod some fixed number is possible for a Fibonacci number. Sloane's A189761 gives the sequence of 'good' moduli to use: for example, there are only 54 distinct residues mod 39088169 that contain Fibonacci numbers. A binary search on these lets you quickly remove 99.9998% of possible numbers. (Depending on how large you want to go, a smaller or larger number may be advisable.)

Of course for very small numbers you may choose to do a binary search directly before checking residues to the chosen modulus.

For numbers that pass the test, the 5n2 ± 4 test is best, and it's probably sensible to do this directly—the residue test above ensures that the number is not of a prohibited congruence class to your modulus. That is, compute the square root of the number and see if it is close to an integer. If so, square it and test if the result is the original number. The methods of Bernstein's paper "Detecting perfect powers in essentially linear time" (section 8) can be used here if desired.

Note that if n < 0 you need only test 5n2 + 4.

Charles
  • 30,888
  • 4
  • 58
  • 139
2

On another note, many people have mentioned the Binet formula. There is a nice way to see how this formula comes about. The Fibonacci sequence is a recurrence relation, so we can apply difference calculus to the sequence. In my advanced discrete mathematics course, we looked at the Fibonacci sequence, naturally. You can see the notes from the day we derived a formula for it[1]. It is on page 1 and page 2 of [1].

A good text book to take a look at with regards to this is [2].

Let me know if I can help you anymore!

[1] http://www.tylerclark12.com/blog/wp-content/uploads/2010/10/Math_542_9-24.pdf

[2] Kelley, W. & Peterson, A. (2001). Difference Equations: An Introduction with Applications (2nd Ed.). San Diego, CA: Academic Press.

Tyler Clark
  • 1,703
  • 2
  • 15
  • 20
1

Using integers only, I would use Binary Search. Certainly you can compute $F_n$ only with integers, the simplest way is matrix exponentiation. Using Binary Search you can find numbers ``near'' your number $x$ and you will find either $x = F_n$ or $F_{n+1} > x > F_n$. I suppose this method is generic for anything monotone you can compute fast. To initiliaze the binary search, just keep doubling $ F_{2n} $

EDIT: Binary search allows you to search for a number x in a sorted "array" F[] (in the programming sense). Use this method to search for your number. When you need F[n] just compute $F_n$. This will work because the sequence is strictly increasing except for the initial 1,1.

jerr18
  • 405
  • 3
  • 11
0

If $X^2 \pm nX -(n^2-1)=0 $ has positive integer solutions for $X$ then $n$ is in the sequence and the solutions are the numbers before and after it in the sequence. This is because if you take any number in the sequence to the $4$th power and subtract the product of the two numbers before it and the two numbers after it the answer will be $1$.

vitamin d
  • 5,547
  • 8
  • 13
  • 37