You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
169 lines
5.7 KiB
169 lines
5.7 KiB
import numpy as np
|
|
np.set_printoptions(suppress=True) # (pour mieux arrondir à 0 lors des print)
|
|
from numpy.polynomial.polynomial import polyval
|
|
|
|
import math
|
|
|
|
import matplotlib.pyplot as plt
|
|
|
|
# On active le "mode interactif" de pyplot. Ainsi, les plt.show() ne sont plus nécessaires.
|
|
plt.ion()
|
|
|
|
# --------------------------------------------------------------------------------------
|
|
# Fonction de "fin temporaire" pendant l'avancée du TP. Attend une frappe Entrée, puis quitte le script.
|
|
|
|
def stop_ici():
|
|
plt.pause(0.1) # nécessaire pour que matplotlib ait le temps d'afficher les figures
|
|
input()
|
|
exit()
|
|
|
|
# --------------------------------------------------------------------------------------
|
|
# Tous les passages indiqués "TODO()" sont à remplacer par vos soins
|
|
|
|
def TODO():
|
|
print("à vous!")
|
|
stop_ici()
|
|
|
|
# --------------------------------------------------------------------------------------
|
|
# Cette petite fonction sert à tracer les flèches avec une syntaxe un peu plus intuitive que le code matplotlib de base.
|
|
# - xdepart, ydepart : coordonnées du point d'attache de la flèche
|
|
# - xfleche, yfleche : longueurs de la flèche en x et en y
|
|
|
|
def myfleche(xdepart, ydepart, xfleche, yfleche):
|
|
plt.annotate("", (xdepart+xfleche,ydepart+yfleche) , (xdepart,ydepart),
|
|
arrowprops={'color':'red','shrink': 0,'width':0.02}, annotation_clip=False)
|
|
|
|
|
|
|
|
#################################################################################################
|
|
###
|
|
### EXERCICE 4 : Interpolation d'Hermite en 1D
|
|
###
|
|
#################################################################################################
|
|
|
|
|
|
|
|
# Comme expliqué dans le sujet pdf, le but est de trouver un polynôme qui passe par des points imposés
|
|
# (==> c'est ça, l'interpolation) mais avec la contrainte additionnelle que le polynôme doit aussi
|
|
# respecter des **valeurs imposées pour sa dérivée** aux mêmes points.
|
|
|
|
|
|
# Pour le moment, on se donne uniquement 2 points d'interpolation, aux abscisses t=1 et t=2.
|
|
|
|
### Cibles (aux points t=1,2)
|
|
ys = 2,5 # ordonnées
|
|
ds = 4,-3 # nombres dérivés
|
|
|
|
# Affichage du problème à résoudre : 2 points cible, ainsi que leurs *dérivées* cible:
|
|
|
|
plt.close('all')
|
|
plt.figure()
|
|
plt.title("Le problème d'interpolation à résoudre")
|
|
plt.xlabel('t')
|
|
plt.ylabel('P(t)')
|
|
for i in range(0,2):
|
|
plt.plot(i+1,ys[i],marker='o',color='blue')
|
|
h = 0.2 # écart h de l'approximation affine (détermine la longueur de la flèche)
|
|
myfleche(i+1, ys[i], h, h*ds[i])
|
|
plt.axis('equal') # (essayer aussi avec cette ligne commentée, parfois le résultat est mieux)
|
|
|
|
print('''(Question papier) On cherche un polynôme P(X) de degré 3
|
|
P(X) = u + v.X + w.X^2 + z.X^3
|
|
qui INTERPOLE ces 2 points ET les 2 dérivées correspondantes, c'est-à-dire qui vérifie
|
|
|
|
P(t)=y et P'(t)=d
|
|
|
|
pour chacun des 2 points cible. Soit, ici :
|
|
P(1) = 2
|
|
P(2) = 5
|
|
P'(1) = 4
|
|
P'(2) = -3
|
|
Montrez que ces 4 équations constituent un *système linéaire* sur les 4 coefficients inconnus (u,v,w,z).
|
|
Précisez la matrice de ce système (appelons-la A), et le vecteur du second membre (appelons-le b).
|
|
''')
|
|
|
|
A = TODO()
|
|
b = TODO()
|
|
|
|
stop_ici() # ---------- Supprimez cette ligne une fois que le code avant fonctionne ------------------
|
|
|
|
# --------------------------------------------------------------------------------------
|
|
print("-"*80)
|
|
|
|
|
|
print("Trouvez le polynôme P (c'est-à-dire, les coefficients u,v,w,z) recherchés.")
|
|
|
|
p = TODO()
|
|
|
|
stop_ici() # ---------- Supprimez cette ligne une fois que le code avant fonctionne ------------------
|
|
|
|
# --------------------------------------------------------------------------------------
|
|
print("-"*80)
|
|
|
|
|
|
print("Dans la même figure que précédemment, représentez le graphe du polynôme P. Vérifiez qu'il INTERPOLE bien les 2 points imposés avec les 2 valeurs de dérivée imposées.")
|
|
|
|
# Discrétisation de l'intervalle [1,2] en 200 points, puis représentation de P(t) sur cet intervalle:
|
|
TODO()
|
|
|
|
stop_ici() # ---------- Supprimez cette ligne une fois que le code avant fonctionne ------------------
|
|
|
|
# --------------------------------------------------------------------------------------
|
|
print("-"*80)
|
|
|
|
|
|
print('''Testez votre code avec d'autres valeurs pour les cibles "ys" et "ds" choisies
|
|
plus haut (mais toujours avec 2 points uniquement, car vous n'avez pas encore
|
|
implémenté la version générale).
|
|
Vérifiez que votre interpolation fonctionne bien à chaque fois.
|
|
|
|
(Indice si cela ne fonctionne pas : définissez-vous le vecteur b de manière suffisamment générique ?)''')
|
|
|
|
stop_ici() # ---------- Supprimez cette ligne une fois que le code avant fonctionne ------------------
|
|
|
|
# --------------------------------------------------------------------------------------
|
|
print("-"*80)
|
|
|
|
|
|
### Une fonction d'interpolation d'Hermite (pour seulement 2 points)
|
|
####################################################################
|
|
|
|
|
|
print('''Encapsulez votre code des questions précédentes dans une fonction, qui:
|
|
- prend en entrée une liste d'ordonnées ys=[y1,y2] et une liste de dérivées ts=[t1,t2]
|
|
- renvoie l'unique polynôme interpolateur de degré 3 tel que
|
|
P(1) = y1
|
|
P(2) = y2
|
|
P'(1) = t1
|
|
P'(2) = t2
|
|
''')
|
|
|
|
def interpol_hermite(ys,ds):
|
|
TODO()
|
|
return p
|
|
|
|
# Test de votre fonction:
|
|
|
|
### Cibles (aux instants t=1,2)
|
|
ys = 3,5 # ordonnées
|
|
ds = -4,-3 # nombres dérivés
|
|
|
|
plt.close('all')
|
|
plt.figure()
|
|
plt.title("Test de la fonction interpol_hermite")
|
|
for i in range(0,2):
|
|
plt.plot(i+1,ys[i],marker='o',color='blue')
|
|
h = 0.2 # écart h de l'approximation affine (détermine la longueur de la flèche)
|
|
myfleche(i+1, ys[i], h, h*ds[i])
|
|
t = np.linspace(1,2,200)
|
|
p = interpol_hermite(ys,ds)
|
|
plt.plot(t,polyval(t,p))
|
|
plt.axis('equal') # (essayer aussi avec cette ligne commentée, parfois le résultat est mieux)
|
|
plt.xlabel('t')
|
|
plt.ylabel('P(t)')
|
|
|
|
########################################
|
|
input()
|
|
|
|
|