three fibonacci series
TRANSCRIPT
-
8/10/2019 Three Fibonacci Series
1/5
Part ThreeThe Fibonacci Series
"Nectar of the gods"
J. Hamilton
It is well known in civilized circles that no discussion of computational methods is complete without at least one reference to
the Fibonacci Series.
Recursion without branching
This function begins summing as it makes the recursive call. Notice that each call generates only one additional call (no
branching).
No safety net
When you giveMathematicamultiple patterns, it will try to match the most specific pattern first
Clear@fibD;
fib@a_, b_, n_IntegerD:=fib@b, a + b, n - 1D;
fib@a_, b_, 0D:=a;
fib@a_, b_, 1D:=b;
fib::usage = "Arguments are a, b, n where a
and b are the initial numbers and n is the number of steps.";
This looks pretty good unless you have a clueless user. Let's try:
fib@a_, b_, -5D:="Enough already";
fib@1, 1, -1D
Enough already
Safer
We limit the actions of the clueless (such as myself before AM coffee) by using an explicit condition in the function
definition.
Clear@fibD;
fib@a_, b_, n_Integer ; n >1D:=fib@b, a + b, n - 1D;
fib@a_, b_, 0D:=a;
fib@a_, b_, 1D:=b;
Let's try this again:
Part Three Fibonacci Series.nb 1
-
8/10/2019 Three Fibonacci Series
2/5
fib@a_, b_, -5D:="Enough already";
fib@1, 1, -1D
fib@1, 1, -1D
Now the function is left unresolved because none of the patterns match the input. If you wanted to you could also add one
more pattern to catch "none of the above". The triple underscore matches a sequence of zero, one, or more entries of any-thing. This would insure that the function is always resolved.
fib@___D:="This is the most general pattern.";
fib@1, 1, -1D
This is the most general pattern.
fib@D
This is the most general pattern.
fib@a, b, , d, 8a, b, c 1D :=fib@b, a + b, n - 1D
fib@a_, b_, 0D:=a
fib@a_, b_, 1D:=b
fib@a_, b_, -5D:= Enough already
fib@___D:=This is the most general pattern.
Part Three Fibonacci Series.nb 2
-
8/10/2019 Three Fibonacci Series
3/5
Recursion with branching
Each of the following versions of the Fibonacci function makes two recursive calls. The slow version saves none of the
intermeduate values, while the fast version saves every (new) intermediate value. The difference in computational time is
dramatic as n increases.
Computing (and recomputing) every node
Notice that the values for n=0 and 1 are defined using = (immediate assignment) rather then := (delayed assignment) in the
fibfuction above.
Clear@slowfibD;
slowfib@n_Integer ; n >1D:=slowfib@n - 1D + slowfib@n - 2D;
slowfib@0D = 1;
slowfib@1D = 1;slowfib::usage ="Don't use this function";
Here is the computational time and the result of the functional evaluation. Because no intermediate values are stored, the
every path in the tree must be traversed. On this machine the time for n=25 was about 1 second, ... then 4 seconds at n=28, ...
now this.
Timing@slowfib@30DD
811.216 Second, 13462691D:=slowfib@n -1D + slowfib@n - 2D
Computing once and storing
Clear@fastfibD;
fastfib@n_Integer ; n >1D:=fastfib@nD = fastfib@n - 1D + fastfib@n - 2D;
fastfib@0D = 1;
fastfib@1D = 1;
fastfib::usage ="This function is fast but uses memory";
Part Three Fibonacci Series.nb 3
-
8/10/2019 Three Fibonacci Series
4/5
Here is the computational time and the result of the functional evaluation. Because intermediate values are stored, only the
first path must be traversed. I run into the default limit on the number of recursive steps before I use a measurable amount of
time computing the answer.
Timing@fastfib@30DD
80. Second, 13462691D:=fastfib@nD =fastfib@n -1D + fastfib@n - 2D
Part Three Fibonacci Series.nb 5