#!/bin/python3

from random import randint
from math   import log
from math   import sqrt
import time
import timeit
import matplotlib.pyplot as plt
import argument as arg

def fibit( n ) :
    x = 0
    y = 1
    i = 2
    while  i <= n :
        y, x = y+x, y
        i = i + 1
    return y

def prod( X, Y ) :
    R = [[0,0], [0,0] ]
    for i in range(0,2 ) :
        for j in range(0,2 ) :
            for k in range(0,2 ) :
                R[i][j] += X[i][k] * Y[k][j] 
    return R

def expomat( X, n ) :
    Y = [ [1,0], [0,1] ]
    while ( n > 0 ) :
        if ( n & 1 == 1 ) :
            Y = prod(Y, X )
        X = prod( X, X)
        n = n // 2
    return Y

def fibmat( n ) :
    F =[ [ 1, 1 ], [1 ,0] ]
    X = expomat( F, n   )
    return X[0][1]

arg.cmdline()

print( 'r=', arg.repetition, 'i=',arg.iteration )
x = []
y = []
z = []
Y = []
Z = []
A = 1E-8*1.4
B = 1E-8*1.4

for n in  range(100 , arg.iteration  , 10  ) :
    x.append( n )
    #deb = time.process_time()
    deb= timeit.default_timer()
    for i in range(0, arg.repetition ) :
        fibit(n) 
    #fin = time.process_time()
    fin= timeit.default_timer()
    y.append( (fin - deb) / log(n)   )
    Y.append( A*log(n) )
    #deb = time.process_time()
    deb= timeit.default_timer()
    for i in range(0, arg.repetition ) :
        fibmat(n) 
    #fin = time.process_time()
    fin= timeit.default_timer()
    z.append( (fin - deb)/ log(n) )
    Z.append( B*log(n))

plt.title("Fibonacci : itératif vs matricielle")
plt.ylabel('temps')
plt.xlabel('n')
plt.plot(x, y, label="itératif")
plt.plot(x, z, label="matricielle")
#plt.plot(x, Y, label="A*n*log n")
#plt.plot(x, Z, label="B *n^1.5*log n")
plt.legend()
plt.grid(True)

plt.show()
plt.close()


