Nth Fibonacci number for n up to 10 ^ 19?

I am trying to make a program to find the nth Fibonacci number for 1 <n <10 ^ 19.

Here is my code using dynamic programming.

memo = {}
def fib(n):
    if n in memo:
        return memo[n]
    if n <= 2:
        f = 1
    else:
        f = fib(n-1) + fib(n-2)
    memo[n]=f
    return f
print fib(input()) % 1000000007

My code does not seem to work for large numbers. I get an incorrect response error. Any suggestions?

+4
source share
4 answers

Getting the Nth Fibonacci number when N is 10 ^ 19 does not work if you do it naively (at least I think it will not work).

There is a much better way to do this. And this technique works with a lot of “like this” series. He called the matrix of the Q the Fibonacci .

enter image description here

Where

enter image description here

:

, A B:

enter image description here

. , , , 1000- , .

, , 10 ^ 19, ( ) .

. x ^ N , N, ..

x**100 == x**90 * x**10

, , :

x**2 , x*x - . x*x*x*x , (x**2)**2, . , . , 2 ( , ),

X**100 == X**64 * X**32 * X**4

.

X**100 == (((((X**2)**2)**2)**2)**2)**2 + ...

, , , , Q.

, :

fib_matrix = [[1,1],
              [1,0]]

def matrix_square(A, mod):
    return mat_mult(A,A,mod)


def mat_mult(A,B, mod):
  if mod is not None:
    return [[(A[0][0]*B[0][0] + A[0][1]*B[1][0])%mod, (A[0][0]*B[0][1] + A[0][1]*B[1][1])%mod],
            [(A[1][0]*B[0][0] + A[1][1]*B[1][0])%mod, (A[1][0]*B[0][1] + A[1][1]*B[1][1])%mod]]


def matrix_pow(M, power, mod):
    #Special definition for power=0:
    if power <= 0:
      return M

    powers =  list(reversed([True if i=="1" else False for i in bin(power)[2:]])) #Order is 1,2,4,8,16,...

    matrices = [None for _ in powers]
    matrices[0] = M

    for i in range(1,len(powers)):
        matrices[i] = matrix_square(matrices[i-1], mod)


    result = None

    for matrix, power in zip(matrices, powers):
        if power:
            if result is None:
                result = matrix
            else:
                result = mat_mult(result, matrix, mod)

    return result

print matrix_pow(fib_matrix, 10**19, 1000000007)[0][1]

, .

+7

O (n) . , " " F (n) O (log (n )).

F (2n-1) = F (n-1) ^ 2 + F (n) ^ 2

F (2n) = (2 * F (n-1) + F (n)) * F (n)

, , .

+4

Python 1000 (). , :

>>> import sys
>>> sys.getrecursionlimit()

-, , Python 3.2 ( , print), @functools.lru_cache(maxsize=128, typed=False) :

import functools

@functools.lru_cache()
def fib(n):
    if n <= 2:
        return 1
    else:
        return fib(n-1) + fib(n-2)

, . - , , "memoize", , 2 .

, .

, n, 10**19, , Python, OverflowError.

+2

, 1E19 , :

import decimal
import operator


def decimal_range(start, stop, step=1):
    """Provides an alternative to `xrange` for very high numbers."""
    proceed = operator.lt
    while proceed(start, stop):
        yield start
        start += step


def fib(n):
    """
    Computes Fibonacci numbers using decimal.Decimal for high 
    precision and without recursion
    """
    a, b = decimal.Decimal(0), decimal.Decimal(1)
    for i in decimal_range(0, n):
        a, b = b, a + b
    return a

26,5 1E6, :

In [26]: %time f2(n)
CPU times: user 26.4 s, sys: 130 ms, total: 26.5 s
Wall time: 26.5 s
Out[26]: Decimal('1.953282128707757731632014830E+208987')

An iterator is taken from this SO stream with minimal modifications, and a function fibcan be found in this other stream .

+1
source

All Articles