#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Jun 21 16:14:11 2025

@author: jurinestephane
"""

## Exemple 1 = tracer un graphique
import matplotlib.pyplot as plt # Module pour tracer les graphiques
# Creation des deux listes de meme longueur
x=[0,1,2,3,4,5,6]
y=[0,1,4,9,16,25,36]
plt.figure(1) #creation d'une fenetre graphique de nom 1
plt.plot(x,y) # Trace de la courbe : y en fonction de x
plt.show() # montre la fenetre

## Exemple 2 = options graph
import matplotlib.pyplot as plt # Module pour tracer les graphiques
x=[0,1,2,3,4,5,6]
y=[0,1,4,9,16,25,36]
plt.figure(1)
plt.title(''Ma premiere figure'') #titre de la figure
plt.xlabel(''Nombre'') # titre de l'axe x
plt.ylabel(''Carre du nombre'') # titre de l'axe y
plt.xlim(0, 6) #valeurs extremes de l'axe x
plt.ylim(0, 36) #valeurs extremes de l'axe y
plt.plot(x, y, '+',label = ''ma courbe'') #le nom de la legende
plt.legend()  #ajout d'une legende
plt.grid(True) # ajout d'une grille de fond
plt.show()

## Exemple 3 = barres d'erreur
import matplotlib.pyplot as plt
import numpy as np
x=np.array([0,1,2,3,4,5,6,7,8,9,10])
y = np.array([3, 4.2, 4.9, 6.2, 6.8, 8, 8.8, 10.3, 10.8, 12, 13.1])
uy = np.array([2, 1, 2.5, 0.5, 1, 2, 2.5, 0.5, 3, 2, 1.3]) # Incertitude-type sur y
plt.figure(1)
plt.errorbar(x, y, yerr=uy,  lw=0, marker='o',  elinewidth=1.5, capsize=5)
plt.xlabel("x")
plt.ylabel("y")
plt.show()

## Exemple 4 = régression linéaire
import matplotlib.pyplot as plt
import numpy as np

# A l'aide de np.array(), les listes sont directement converties en array
x = np.array([0,1,2,3,4,5,6,7,8,9,10])
y = np.array([3, 4.2, 4.9, 6.2, 6.8, 8, 8.8, 10.3, 10.8, 12, 13.1])

# Regression lineaire (= polynomiale d'ordre 1) : y = a x + b
a, b = np.polyfit(x, y, 1) 

# Affichage des parametres dans la console
print('Resultat de la regression lineaire :')
print('a =', a)
print('b =', b)

plt.figure(1)
plt.plot(x, y, 'o', label='Donnees experimentales')
plt.plot(x, a*x+b, label='Regression lineaire')
plt.xlabel("x")
plt.ylabel("y")
plt.xlim(0, 10)
plt.ylim(0, 14)
plt.legend()
plt.show()

## Exemple 5 = Dérivation
import matplotlib.pyplot as plt
import numpy as np

# Parametres 
N = 1000 # Nombre de points 

# Derivation  : syntaxe avec une boucle et liste
x = [i*2*np.pi/N for i in range(N)]
y = [np.cos(X) for X in x]
dy = []  # creation d'une liste vide
...........................
...........................
    
#Derivation : syntaxe avec numpy et slicing
x = np.linspace(0, 2*np.pi, N)
y = np.cos(x)
dynumpy = ...........................

dy_exacte = -np.sin(x) # Calcul de la derivee exacte pour comparaison
# Graphique 
plt.figure(1)
plt.plot(x, dy_exacte, label="Derivee exacte")
plt.plot(x[:-1], dy, lw=4,alpha = 0.5, label="Derivee numerique") # x[:-1] permet d'exclure le dernier point de la liste
plt.plot(x[:-1],dynumpy,lw=8,alpha = 0.1,label = "Derivee numerique numpy")
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
plt.show()

## Exemple 6 = Intégration
import numpy as np 
# Parametres 
N = 10000 # Nombre de points

#integration syntaxe avec listes
x = [i/N*10 for i in range(N)]
y = [X**2 for X in x]
A = 0 # aire initialisee
............................
............................
print('Aire = ',A)

#integration : syntaxe avec numpy et slicing
x = np.linspace(0,10,N)
y = x**2
A = 0 # aire initialisee
...........................
print('Aire = ', A)

## Exemple 7 = Dichotomie
# Definition de l'equation dont on cherche la racine : f(x) = 0
def f(x):
    return x**2 - 16
# Parametres : intervalle de recherche et precision
a=0
b=10
epsilon=1e-9
# Algorithme de dichotomie
Delta=b-a
while ...................:
    m = (a+b)/2 # Milieu de l'intervalle
    Delta = b - a # Largeur de l'intervalle mis a jour
    if f(m)==0:  #Cas f(m)= 0
        break
    elif f(a)*f(m)>0:  
        ..................
    else: 
        ...................
print('Racine =', m)

## Exemple 8 = Bissect
from scipy.optimize import bisect 
# Definition de l'equation dont on cherche la racine : f(x) = 0
def f(x):
    return x**2 - 16
racine = bisect(f, 0, 10) # On cherche une racine de f entre 0 et 10
print('Racine =', racine)

## Exemple 8 = Euler 1
import matplotlib.pyplot as plt
import numpy as np

# Parametres 
E = 5 # Tension d'alimentation (V)
tau=5e-3 #Constante de temps(s) : 5ms
u0 = 0  # Condition initiale (V)
dt = 1e-5   # Pas d'integration
t = np.arange(0, 8*tau, dt) # Array allant de 0 a 8*tau, avec un pas dt : t = [0, dt, 2*dt, ..., 8*tau]
N = len(t) # Longueur de l'array t
u = np.zeros(N) # Creation d'un array vide (rempli de 0) de longueur N
u[0] = 0 # Condition initiale

#Methode d'Euler
for i in ...................:
    ...................................
# Solution exacte 
sol = E * (1 - np.exp(-t/tau))

# Trace
plt.figure(1)
plt.plot(t, sol, lw=5, alpha=0.5, label="Solution reelle")
plt.plot(t, u, lw=2, label="Methode d'Euler")
plt.xlabel("t (s)")
plt.ylabel("u (V)")
plt.legend()
plt.show()

## Exemple 9 = odeint
import numpy as np
import matplotlib.pyplot as plt
import scipy.integrate.odeint as odeint

E = 1
tau = 1
u0 = np.array([0])
t0, tf, pas = 0, 5*tau, tau/100
t1 = np.arange(t0, tf, pas)

# Exemple : Resolution de u'+u(t)/tau=E/tau ; u(0)=0
def dudt(u, t):
    """Cette fonction doit renvoyer ce a quoi u' est egal"""
    return ..........................

u = .........................

plt.figure(1)
plt.plot(t1, u, label=r"$u(t)$ odeint")
plt.legend()
plt.show()

## Exemple 10 = odeint ordre 2
import matplotlib.pyplot as plt
import numpy as np
from scipy.integrate import odeint

# Parametres 
w0 = 5
T = 2*np.pi/w0
x0 = (np.pi/4, 0) #conditions initiales sur la position et la vitesse

# Resolution de l'ED 
def deriv(x, t):
     """Cette fonction doit renvoyer ce a quoi x' est egal"""
    dx = .................................
    return dx

t = np.linspace(0, 8*T, 1000)
x = odeint(deriv, x0, t)

# On extrait les valeurs de theta et de sa derivee depuis x
theta=x[:,0]
dtheta=x[:,1]

# Graphique 
plt.figure(1)
plt.plot(t, theta, c='r', ls='-', lw=2) 
plt.xlabel("t (s)")
plt.ylabel("theta (rad)")
plt.show()
