# -*- coding: utf-8 -*-
"""
Created on Fri Oct  4 13:43:18 2024

@author: arnau
"""

import numpy as np
import matplotlib.pyplot as plt

def Euler(F,y0,a,b,n):
    '''
    Entrées : F la fonction définissant l'équation différentielle
              a,b les extremités de l'intervalle de définition d'une solution
              y0 une condition initiale
              n le nombre de subdivision
    Sortie : une approximation de la solution de y'=F(y) sur [a,b] telle que y(a)=y0
    '''
    h=(b-a)/n  # pas 
    Y=[y0]
    for k in range(1,n+1):
        Y.append(Y[-1]+h*F(Y[-1]))  # liste des approximation de y(a+k(b-a)/n)
    return Y



#%% Pour y'=y càd F: y --> y et y0=1 la solution exacte est exp

def F(y):
    ''' on considerera l'ED y'=F(y)
    '''
    return y

y0=1
a=0
b=2
n=[2,10,50]

for _ in n :
    T = [a+k*(b-a)/_ for k in range(_+1)]
    Y = Euler(F,y0,a,b,_)
    plt.plot(T,Y)
    
plt.plot(np.linspace(a,b,1000),np.exp(np.linspace(a,b,1000)))
plt.show()

#%% Exemple du cours y'=yln(y) avec y(0)=e . 

def F2(y):
    ''' on considerera l'ED y'=F(y)
    '''
    return y*np.log(y)

def solution_exacte(t):
    return np.exp(np.exp(t))


for _ in n :
    T = [k*1/_ for k in range(_+1)]
    Y = Euler(F2,np.e,0,1,_)
    plt.plot(T,Y)
    
plt.plot(np.linspace(0,1,1000),solution_exacte(np.linspace(0,1,1000)))
plt.show()

#%% Erreur |y_n-exp(t_n)|=|y_n-e^2| pour n subdivisions

E=[]
for n in range(1,100):
    E.append(np.abs(Euler(F,y0,a,b,n)[-1]-np.e**2)) 

plt.plot(E)
plt.show