# -*- coding: utf-8 -*-
"""
Created on Mon Jul  4 17:34:03 2022

@author: starons
"""

"""
Encadre la valeur de l'intégrale I d'une fonction f sur l'intervalle [a,b] 
par la méthode des rectangles. Ou comment intégrer l'X en 3 ans ? 
"""

# On importe les bibliothèques utiles
# -----------------------------------
import numpy as np 

# On définit la fonction dont on cherche une integrale
# ---------------------------------------------------- 
def mafonction(x):
    return 1/np.sqrt(np.cos(x))

# Bornes de l'integrale
# ---------------------
inf = 0.000001
sup = np.pi/2

# Méthode des rectangles à droite
# -------------------------------
def droite(f,a,b,N):
    X = np.linspace(a,b,N)        # Crée un tableau numpy contenant N valeurs de x régulièrement espacées dans l'intervalle [a,b]
    Y = f(X)                      # La fonction f est appliquée à chaque élément du tableau X
    I=sum(Y[0:N-1])*(b-a)/(N-1)   # On somme toutes les valeurs prises par f entre a et b SAUF LA DERNIERE et on multiplie par le pas.  
    return I

##########################################################################################
# ATTENTION : Y[i:j] renvoie un tableau constitué des éléments de Y numéroté de i à j-1 !# 
##########################################################################################

# Méthode des rectangles à gauche
# -------------------------------
def gauche(f,a,b,N):
    X = np.linspace (a,b,N)        
    Y = f(X)                       
    I = sum(Y[1:N])*(b-a)/(N-1)   # On fait de même mais en EXCLUANT LA PREMIERE valeur. 
    return I

# Il est intéressant de constater que plus il y a de rectangles... mieux c'est !
# ------------------------------------------------------------------------------   
print("La valeur de l'integrale est comprise entre {:.4f} et {:.4f}".format(droite(mafonction,inf,sup,10),gauche(mafonction,inf,sup,10)))
print("La valeur de l'integrale est comprise entre {:.4f} et {:.4f}".format(droite(mafonction,inf,sup,100),gauche(mafonction,inf,sup,100)))
print("La valeur de l'integrale est comprise entre {:.4f} et {:.4f}".format(droite(mafonction,inf,sup,100000),gauche(mafonction,inf,sup,1000)))

# Une fonction préprogrammée dans Python permet d'évaluer l'integrale par une méthode similaire mais optimisée !
# -------------------------------------------------------------------------------------------------------------- 
from scipy.integrate import quad
résultat,erreur=quad(mafonction,inf,sup)
print("Avec la fonction quad, Python trouve :",résultat)
print("Il estime aussi l'erreur commise :",erreur)