http://scottsievert.github.io/blog/2015/01/31/the-mysterious-eigenvalue/

The Fibonacci problem is a well known mathematical problem that models population growth and was conceived in the 1200s. Leonardo
of Pisa
 aka Fibonacci decided to use a recursive equation: xn=xn−1+xn−2 with
the seed values x0=0 and x1=1.
Implementing this recursive function is straightforward:1

1
2
3
4
def fib(n):
if n==0: return 0
if n==1: return 1
else: return fib(n-1) + fib(n-2)

Since the Fibonacci sequence was conceived to model population growth, it would seem that there should be a simple equation that grows almost exponentially. Plus, this recursive calling is expensive both in time and memory.2.
The cost of this function doesn’t seem worthwhile. To see the surprising formula that we end up with, we need to define our Fibonacci problem in a matrix language.3

[xnxn−1]=xn=A⋅xn−1=[1110]⋅[xn−1xn−2]

Calling each of those matrices and vectors variables and recognizing the fact that xn−1 follows
the same formula as xn allows
us to write

xn=A⋅xn−1=A⋅A⋯A⋅x0=An⋅x0

where we have used An to
mean n matrix
multiplications
. The corresponding implementation looks something like this:

1
2
3
4
5
def fib(n):
A = np.asmatrix('1 1; 1 0')
x_0 = np.asmatrix('1; 0')
x_n = np.linalg.matrix_power(A, n).dot(x_0)
return x_n[1]

While this isn’t recursive, there’s still an n−1 unnecessary
matrix multiplications. These are expensive time-wise and it seems like there should be a simple formula involving n.
As populations grow exponentially, we would expect this formula to involve scalars raised to the nth
power. A simple equation like this could be implemented many times faster than the recursive implementation!

The trick to do this rests on the mysterious and intimidating eigenvalues and eigenvectors. These are just a nice way to view the same data but they have a lot
of mystery behind them. Most simply, for a matrix A they
obey the equation

A⋅x=λ⋅x

for different eigenvalues λ and
eigenvectors x.
Through the way matrix multiplication is defined, we can represent all of these cases. This rests on the fact that the left multiplied diagonal matrix Λjust
scales each xi by λi.
The column-wise definition of matrix multiplication makes it clear that this is represents every case where the equation above occurs.

A⋅[x1x2]=[x1x2]⋅[λ100λ2]

Or compacting the vectors xi into
a matrix called X and
the diagonal matrix of λi’s
into Λ,
we find that

A⋅X=X⋅Λ

Because the Fibonacci eigenvector matrix is invertible,4

A=X⋅Λ⋅X−1

And then because a matrix and it’s inverse cancel

An=X⋅Λ⋅X−1⋅…⋅X⋅Λ⋅X−1=X⋅Λn⋅X−1

Λn is
a simple computation because Λ is
a diagonal matrix: every element is just raised to the nth
power. That means the expensive matrix multiplication only happens twice now. This is a powerful speed boost and we can calculate the result by substituting for An

xn=X⋅Λn⋅X−1⋅x0

For this Fibonacci matrix, we find that Λ=diag(1+5√2,1−5√2)=diag(λ1,λ2).
We could define our Fibonacci function to carry out this matrix multiplication, but these matrices are simple: Λ is
diagonal and x0=[1;0].
So, carrying out this fairly simple computation gives

xn=15√(λn1−λn2)≈15√⋅1.618034n

We would not expect this equation to give an integer. It involves the power of two irrational numbers, a division by another irrational number and even the golden ratio phi ϕ≈1.618!
However, it gives exactly the Fibonacci numbers – you can check yourself!

This means we can define our function rather simply:

1
2
3
4
5
6
7
def fib(n):
lambda1 = (1 + sqrt(5))/2
lambda2 = (1 - sqrt(5))/2
return (lambda1**n - lambda2**n) / sqrt(5)
def fib_approx(n)
# for practical range, percent error < 10^-6
return 1.618034**n / sqrt(5)

As one would expect, this implementation is fast. We see speedups of roughly 1000 for n=25,
milliseconds vs microseconds. This is almost typical when mathematics are applied to a seemingly straightforward problem. There are often large benefits by making the implementation slightly more cryptic!

I’ve found that mathematics5 becomes
fascinating, especially in higher level college courses, and can often yield surprising results. I mean, look at this blog post. We went from a expensive recursive equation to a simple and fast equation that only involves scalars. This derivation is one I
enjoy and I especially enjoy the simplicity of the final result. This is part of the reason why I’m going to grad school for highly mathematical signal processing. Real world benefits + neat
theory = <3.

  1. The complete implementation can be found on Github.

  2. Yes, in some languages some compilers are smart enough to get rid of recursion for some functions.

  3. I’m assuming you have taken a course that deals with matrices.

  4. This happens when a matrix is diagonalizable.

  5. Not math. Courses beyond calculus deserve a different name.

Posted by Scott
Sievert Jan 31st, 2015  math

Applying Eigenvalues to the Fibonacci Problem的更多相关文章

  1. [Algorithm] Fibonacci problem by using Dynamic programming

    vThere are three ways to solve Fibonacci problem Recursion Memoize Bottom-up 'First Recursion approa ...

  2. Codeforces 1264F - Beautiful Fibonacci Problem(猜结论+找性质)

    Codeforces 题面传送门 & 洛谷题面传送门 一道名副其实(beautiful)的结论题. 首先看到这道设问方式我们可以很自然地想到套用斐波那契数列的恒等式,注意到这里涉及到 \(F_ ...

  3. hdu 1568 Fibonacci 数学公式

    Fibonacci Problem Description 2007年到来了.经过2006年一年的修炼,数学神童zouyu终于把0到的Fibonacci数列(f[0]=0,f[1]=1;f[i] = ...

  4. HDU - 1588 Gauss Fibonacci (矩阵高速幂+二分求等比数列和)

    Description Without expecting, Angel replied quickly.She says: "I'v heard that you'r a very cle ...

  5. HDU 1588 Gauss Fibonacci(矩阵快速幂)

    Gauss Fibonacci Time Limit: 3000/1000 MS (Java/Others)     Memory Limit: 32768/32768 K (Java/Others) ...

  6. HDU:Gauss Fibonacci(矩阵快速幂+二分)

    http://acm.hdu.edu.cn/showproblem.php?pid=1588 Problem Description Without expecting, Angel replied ...

  7. HDU 4099 Revenge of Fibonacci Trie+高精度

    Revenge of Fibonacci Problem Description The well-known Fibonacci sequence is defined as following: ...

  8. 跨平台的CStdString类,实现了CString的接口

    在实际工作中,std的string功能相对于MFC的CString来说,实在是相形见绌. CStdString类实现了CString的功能,支持跨平台. // ==================== ...

  9. Minimum Depth of Binary Tree 解答

    Question Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along ...

随机推荐

  1. U3D prefab

    1,prefab相当于一个类,字面意思就是预设,预先设计好的类.把一个prefab拖放到场景中就生成了一个实例,把二个prefab放到场景中就生成了两个实例. 不同的实例独立动作,拥有自己独立的状态与 ...

  2. Oracle数据库,数字强制显示2位小数(转)

    Oracle数据库,数字强制显示2位小数 在银行.财务等对数字要求敏感的系统中,数字的显示一般有着严格的要求.今遇到一个需求,如题,要求将数字以两位小数的格式显示,如果没有小数,则强制显示为0.例如: ...

  3. 配置错误定义了重复的“system.web.extensions/scripting/scriptResourceHandler” 解决办法

    今天遇到了这个问题, 电脑系统:vs2010 win7系统 iis7 我运行在iis中配置的那个网站后,报错:错误代码 0x800700b7 配置错误定义了重复的“system.web.extensi ...

  4. pandas 透视表 pivot_table

    The function pandas.pivot_table can be used to create spreadsheet-style pivot tables. It takes a num ...

  5. 在opencv3中实现机器学习之:利用逻辑斯谛回归(logistic regression)分类

    logistic regression,注意这个单词logistic ,并不是逻辑(logic)的意思,音译过来应该是逻辑斯谛回归,或者直接叫logistic回归,并不是什么逻辑回归.大部分人都叫成逻 ...

  6. linux(centos 6.4)下安装php memcache服务端及其客户端(详细教程)

    前言 在搭建个人博客时,由于没有使用任何框架,纯手工code前台和后台,导致遇到许多问题,其中一个问题就是mysql连接导致的页面相应速度异常低.在查询各种途径后,只能考虑使用memcache缓存.在 ...

  7. MPMoviePlayerViewController的使用 (不直接将播放器放到主视图控制器,而是放到一个内部模态视图控制器中)

    其实MPMoviePlayerController如果不作为嵌入视频来播放(例如在新闻中嵌入一个视频),通常在播放时都是占满一个屏幕的,特别是在 iPhone.iTouch上.因此从iOS3.2以后苹 ...

  8. iOS开发系列--音频播放(音效和音乐)播放本地的

    音频 在iOS中音频播放从形式上可以分为音效播放和音乐播放.前者主要指的是一些短音频播放,通常作为 点缀音频,对于这类音频不需要进行进度.循环等控制.后者指的是一些较长的音频,通常是主音频,对于这些音 ...

  9. 20145208 《Java程序设计》第4周学习总结

    20145208 <Java程序设计>第4周学习总结 教材学习内容总结 继承 在学习指导中我了解到继承是符合DRY原则的,DRY(Don't repeat yourself),字面意思来看 ...

  10. 云计算之路-阿里云上:2014年6月11日17点遇到的CPU 100%状况

    今天下午17:00-17:05之间,在请求量没有明显变化的情况下,SLB中的1台云服务器的CPU突然串到100%(当时SLB中一共有3台云服务器),见下图: 造成的直接后果是请求执行时间变得超长,最长 ...