t_veor@sopuli.xyztoProgramming@programming.dev•A Linear Algebra Trick for Computing Fibonacci Numbers FastEnglish
2·
1 year agoIt’s not that hard to check yourself. Running the following code on my machine, I get that the linear algebra algorithm is already faster than the naive algorithm at around n = 100 or so. I’ve written a more optimised version of the naive algorithm, which is beaten somewhere between n = 200 and n = 500.
Try running this Python code on your machine and see what you get:
import timeit
def fib_naive(n):
a = 0
b = 1
while 0 < n:
b = a + b
a = b - a
n = n - 1
return a
def fib_naive_opt(n):
a, b = 0, 1
for _ in range(n):
a, b = b + a, b
return a
def matmul(a, b):
return (
(a[0][0] * b[0][0] + a[0][1] * b[1][0], a[0][0] * b[0][1] + a[0][1] * b[1][1]),
(a[1][0] * b[0][0] + a[1][1] * b[1][0], a[1][0] * b[0][1] + a[1][1] * b[1][1]),
)
def fib_linear_alg(n):
z = ((1, 1), (1, 0))
y = ((1, 0), (0, 1))
while n > 0:
if n % 2 == 1:
y = matmul(y, z)
z = matmul(z, z)
n //= 2
return y[0][0]
def time(func, n):
times = timeit.Timer(lambda: func(n)).repeat(repeat=5, number=10000)
return min(times)
for n in (50, 100, 200, 500, 1000):
print("========")
print(f"n = {n}")
print(f"fib_naive:\t{time(fib_naive, n):.3g}")
print(f"fib_naive_opt:\t{time(fib_naive_opt, n):.3g}")
print(f"fib_linear_alg:\t{time(fib_linear_alg, n):.3g}")
Here’s what it prints on my machine:
========
n = 50
fib_naive: 0.0296
fib_naive_opt: 0.0145
fib_linear_alg: 0.0701
========
n = 100
fib_naive: 0.0652
fib_naive_opt: 0.0263
fib_linear_alg: 0.0609
========
n = 200
fib_naive: 0.135
fib_naive_opt: 0.0507
fib_linear_alg: 0.0734
========
n = 500
fib_naive: 0.384
fib_naive_opt: 0.156
fib_linear_alg: 0.112
========
n = 1000
fib_naive: 0.9
fib_naive_opt: 0.347
fib_linear_alg: 0.152
It’s possible they tried the British layout on their American ANSI keyboard, which is missing the extra key that ISO keyboards have (the one next to enter which the British layout uses for # and ~)?
I’m not actually sure how to press that key at all if you’re using the British layout on an ANSI keyboard