# ======================================================================== #
# RESOLUTION D'UNE EQUATION DIFFERENTIELLE DU PREMIER ORDRE : y' = f(y,t). #
# METHODE D'EULER. SCHEMA EXPLICITE.                                       #
# Programme de base.                                                       #
# Version du 06/11/2015.                                                   #
# ======================================================================== #

# La fonction donnant la dérivée y' en fonction de y et de la variable de référence x.
# ====================================================================================
def f(y,x):
    return (x*y)**0.5

# Le coeur de l'algorithme : le schéma numérique proprement dit.
# ==============================================================
def Euler(y0,a,b,npas):
    # Le pas
    h = (b-a)/npas
    # Initialisations des listes x et y
    x, y = [a], [y0]
    # Le schéma numérique.
    for i in range(1,npas+1):
        x.append(a + i * h)
        y.append(y[-1] + h * f(y[-1],x[-1]))
    return(y[-1])

# Programme principal.
# ====================

# Initialisations
# Conditions initiales
y0, x0, b = 1, 1, 9
# Nombre d'intervalles
n = int(input("Veuillez saisir le nombre de d'intervalles : "))

# Message pour l'équation différentielle proposée
# (A MODIFIER POUR LA RESOLUTION D'UNE AUTRE EQUATION DIFFERENTIELLE)
print("Résolution de y'(x)=sqrt(x*y(x)) avec la condition initiale : y(" + str(x0) + ")=" + str(y0))

# Résolution de l'équation différentielle
print("Approximation de y(" + str(b) + ") par la méthode d'Euler explicite (" + str(n) + " pas) :",Euler(y0,x0,b,n))

# Solution exacte pour la seconde fonction
# (A MODIFIER POUR LA RESOLUTION D'UNE AUTRE EQUATION DIFFERENTIELLE)
print("Valeur exacte de y(" + str(b) + ") : " + str((b*b**0.5+2)**2/9))


# Fin du programme principal.
# ===========================