#################################
########### AGRO 2022 ###########
#################################

## Importations

import matplotlib.pyplot as plt

# # # # # # # # # # # # # # # #
# # # # # QUESTION 1a # # # # #
# # # # # # # # # # # # # # # #

import math as m

r = 2
def sol(t) :
    return m.exp(r*t)

# # # # # # # # # # # # # # # #
# # # # # QUESTION 1b # # # # #
# # # # # # # # # # # # # # # #

def liste(T,h) :
    t = 0
    L = [0]
    while t+h <= T :
        t = t+h
        L.append(t)
    return L

# liste(1,0.2) renvoie la liste : [0,0.2,0.4,0.6,0.8,1]
# liste(1,0.3) renvoie la liste : [0,0.3,0.6,0.9]
# liste(T,h) renvoie la liste des flottants [0,h,2h,...,kh]
# telle que kh <= T et (k+1)h > T.

# # # # # # # # # # # # # # # #
# # # # # QUESTION 1c # # # # #
# # # # # # # # # # # # # # # #

def mystere() :
    Lt = liste(20,10**-2)
    n = len(Lt)
    Ls = []
    for k in range(0,n) :
        Ls.append(sol(Lt[k]))
    plt.plot(Lt,Ls)
    plt.show()

# Ls est la liste [exp(0), exp(0.02), exp(0.04),...,exp(40)]
# (puisque r = 2)
# La fonction 'mystere' représente graphiquement la fonction
# sol : t |---> exp(2t) sur l'intervalle [0,20] avec un pas
# de 10**-2.

# # # # # # # # # # # # # # # #
# # # # # QUESTION 2a # # # # #
# # # # # # # # # # # # # # # #

L = [[3,1], [7], [1,9,8,0]]

# L[1] est la liste [7]
# L[0][1] est l'entier 1
# len(L) vaut 3

L.append(9.75)

# Maintenant, L est la liste [[3,1], [7], [1,9,8,0], 9.75]

# # # # # # # # # # # # # # # #
# # # # # QUESTION 2b # # # # #
# # # # # # # # # # # # # # # #

a = 2

def lapin(x,y) :
    return x - x*y

def lynx(x,y) :
    return -a*y + x*y

# # # # # # # # # # # # # # # #
# # # # # QUESTION 2c # # # # #
# # # # # # # # # # # # # # # #

def resol_1(x0,y0,T,h) :
    x = x0; y = y0
    t = 0
    Lx = [x]
    Ly = [y]
    Lt = [t]
    while t+h <= T :
        x1 = x + h*lapin(x,y)
        y1 = y + h*lynx(x,y)
        t = t + h
        x = x1
        y = y1
        Lt.append(t)
        Lx.append(x)
        Ly.append(y)
    return [Lt, Lx, Ly]

# # # # # # # # # # # # # # # #
# # # # # QUESTION 2d # # # # #
# # # # # # # # # # # # # # # #

x0 = 1; y0 = 0.5; T = 20; h = 10**-2

def trace_pop_1() :
    L = resol_1(x0,y0,T,h)
    plt.plot(L[0],L[1])
    plt.plot(L[0],L[2],'--')
    plt.show()

# L contient 3 listes renvoyées par la fonction resol_1 :
# L[0] qui contient les valeurs de temps tk
# L[1] qui contient les valeurs xk
# (population de lapins à l'instant tk)
# L[2] qui contient les valeurs yk
# (population de lynx à l'instant tk)
# plt.plot(L[0],L[1]) crée les points d'abscisses tk
# et d'ordonnée xk (donc trace la population de lapins
# en fonction du temps)
# plt.plot(L[0],L[2]) crée les points d'abscisses tk
# et d'ordonnée yk (donc trace la population de lynx
# en fonction du temps)
# plt.show() crée la fenêtre graphique.

# # # # # # # # # # # # # # # #
# # # # # QUESTION 2e # # # # #
# # # # # # # # # # # # # # # #

# Sur la figure 1, la courbe en traits pleins est
# celle de la population de lapins en fonction du temps,
# et la courbe en pointillés celle des lynx.
# En effet, tant que les lynx sont peu nombreux, les lapins
# se reproduisent et leur population augmente. Il y a donc
# à manger pour les lynx, dont la population peut augmenter.
# Mais plus les lynx sont nombreux, plus ils mangent
# et la population de lapins se met alors à diminuer,
# ce qui entraîne un peu plus tard une diminution de
# la population de lynx.

# # # # # # # # # # # # # # # #
# # # # # QUESTION 2f # # # # #
# # # # # # # # # # # # # # # #

def fonctionV(x,y) :
    return x-a*m.log(x)+y-m.log(y)

def trace_V_1() :
    [Lt,Lx,Ly] = resol_1(x0,y0,T,h)
    V = []
    for k in range(len(Lx)) :
        v = fonctionV(Lx[k],Ly[k])
        V.append(v)
    plt.plot(Lt,V)
    plt.show()

# # # # # # # # # # # # # # # #
# # # # # QUESTION 3a # # # # #
# # # # # # # # # # # # # # # #

def resol_2(x0,y0,T,h) :
    x = x0; y = y0
    t = 0
    Lx = [x]
    Ly = [y]
    Lt = [t]
    while t+h <= T :
        u = x + h*lapin(x,y)
        w = y + h*lynx(x,y)
        x1 = x + h/2*(lapin(x,y)+lapin(u,w))
        y1 = y + h/2*(lynx(x,y)+lynx(u,w))
        t = t + h
        x = x1
        y = y1
        Lt.append(t)
        Lx.append(x)
        Ly.append(y)
    return [Lt, Lx, Ly]

# # # # # # # # # # # # # # # #
# # # # # QUESTION 3b # # # # #
# # # # # # # # # # # # # # # #

def trace_V_2() :
    [Lt,Lx,Ly] = resol_2(x0,y0,T,h)
    V = []
    for k in range(len(Lx)) :
        v = fonctionV(Lx[k],Ly[k])
        V.append(v)
    plt.plot(Lt,V)
    plt.show()

# on ne change que l'appel à la fonction resol_2
# au lieu de resol_1

# # # # # # # # # # # # # # # #
# # # # # QUESTION 3c # # # # #
# # # # # # # # # # # # # # # #

# La méthode 2 (de Heun) semble plus satisfaisante :
# l'analyse mathématique montre que la fonction V
# est constante pour un couple de solutions (x(t),y(t))
# du système différentiel (S)
# et la figure 2b approche nettement mieux une fonction
# constante que la figure 2a.

# # # # # # # # # # # # # # # #
# # # # # QUESTION 4  # # # # #
# # # # # # # # # # # # # # # #

def trace_pop_2() :
    L = resol_2(x0,y0,T,h)
    plt.plot(L[0],L[1])
    plt.plot(L[0],L[2],'--')
    plt.show()

# Les figures 1 et 3 montrent des courbes qui évoluent
# de façon similaires mais sur la figure 1, les crêtes sont
# de plus en plus élevées, ce qui laisse supposer à long
# terme une population qui, à certains moments, devient
# arbitrairement grande.
# Au contraire, sur la figure 3, on observe que
# les populations de lapins et de lynx sont bornées.

# # # # # # # # # # # # # # # #
# # # # # QUESTION 5  # # # # #
# # # # # # # # # # # # # # # #

# On peut reprendre ici l'explication de la question 2e,
# et ajouter l'observation que les populations de lièvrepins
# et de lynx semblent suivre des cycles périodiques,
# de période 5 (5 ans?)




















