21
$\begingroup$

For Fibonacci numbers we have a nice formula:

$$ \frac{\left(1+\sqrt{5}\right)^n-\left(1-\sqrt{5}\right)^n}{2^{n} \sqrt{5}} $$

We can implement that in Mathematica:

a[n_]:= ((1+Sqrt[5])^n-(1-Sqrt[5])^n)/(2^n Sqrt[5])

a[10] //Expand
(* 55 *)

We need Expand to get rid of all the $\sqrt{5}$'s in the result. For large n, expanding gives very large intermediate results and therefore this function becomes very slow.

However, Mathematica can do numerical computations to any precision. So we can overcome the problem by computing a[n] numerically with a precision at least equal to the number of digits of a[n] and then rounding the result. That can be done as follows:

b[n_Integer?Positive] := With[{z=((1+Sqrt[5])^n-(1-Sqrt[5])^n)/(2^n*Sqrt[5])},
   Round[N[ z, 1+N[Log[10,z]]]]]

b /@ Range[10]
(* {1,1,2,3,5,8,13,21,34,55} *)

Now let us compute a very large Fibonacci number by using this function b and the built in function Fibonacci.

n=600000;
r1=b[n]; // RepeatedTiming
r2=Fibonacci[n]; // RepeatedTiming
r1==r2
(*
{0.000068,Null}
{0.0012,Null}
True
*)

I am very sure that some years ago the function b was slower than the function Fibonacci. But now (version 10.4 and 11.0) it is much faster. Has Fibonacci indeed slowed down so much or is this a timing problem?

$\endgroup$
  • 1
    $\begingroup$ OTOH, if we go further up (e.g. n = 6*^6 and n = 6*^7), your b is only about half as fast as Fibonacci[]. $\endgroup$ – J. M.'s discontentment Oct 4 '16 at 7:30
  • 2
    $\begingroup$ Funny to see this in the HNQ. I presume he did, he lived to 80 in the middle ages... $\endgroup$ – RemcoGerlich Oct 5 '16 at 7:39
30
$\begingroup$

There seems to be some significant caching going on for the b function.

n = 600000;

ClearSystemCache[]
b[n]; // AbsoluteTiming
(* {0.213265, Null} *)

b[n]; // AbsoluteTiming
(* {0.000196, Null} *)

These timings are in version 11.0.1. In version 9.0.1 I get 0.29 s for b[n].

I also tried Do[Fibonacci[n], {1000}] // AbsoluteTiming, and I got 1.25 s in v11 vs 1.6 s in v9.

Conclusions:

  • Later versions of Mathematica seem to be overall faster than older ones.

  • Fibonacci is in reality much faster than b. The caching effects distort the timing.

A better comparison of the two functions would be to time them with several different n:

ClearSystemCache[]
Table[Fibonacci[n], {n, 1, 600000, 10000}]; // AbsoluteTiming
(* {0.031772, Null} *)

ClearSystemCache[]
Table[b[n], {n, 1, 600000, 10000}]; // AbsoluteTiming
(* {5.73996, Null} *)
| improve this answer | |
$\endgroup$
  • 1
    $\begingroup$ So I was strongly mislead by the RepeatedTiming. Many thanks for pointing that out. $\endgroup$ – Fred Simons Oct 4 '16 at 8:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.