Le fichier de ce qui suit est ici.
Marc m'a déjà corrigé ma copie là :)
# Polynômes à une indéterminée: \( \mathbb{R} [X] \)
# 1. Représentation des polynômes
# on représente le polynôme \(a_nX^n+...a_1X+a_0\) par la liste de ses
# coefficients jusqu'à un certain degré, étant entendu qu'après ce degré
# les coefficients sont nuls
# on les ordonne par degré croissant:
# \([a_0,a_1,...,a_n]\)
# par exemple, soit p1 le polynôme \(2X^2-3X+1\)
# en python une liste est une suite d'éléments entre crochets,
# séparés par des virgules
p1=[1,-3,0,2] # le polynôme 2X^3-3X+1
p2=[1,-3,0,2,0] # le même polynôme
p3=[1,3,5] # le polynôme 5X^2+3X+1
# p1 et p2 représentent le même polynôme, mais pour python ce sont des listes différentes.
# quelques fonctions utiles sur les listes:
# range(n) produit la liste des entiers de 0 à n-1: [0,1,2,...,n-1]
# len(s) donne la longueur d'une liste s
# + concatène deux listes
# on accède à l'élément de rang k de la liste p par la syntaxe p[k]
# le premier rang étant le rang 0
p1[0]
p1[1]
p1[2]
# ca tombe bien pour les polynômes: p[k] donne le coefficient de X^k dans p
# mais on peut désirer connaître le coefficient de p pour un degré donné sans connaître le degré de p, il faut donc écrire une fonction qui calcule cela
def coef(p,k):
if k<len(p): return p[k]
else: return 0
# calculons le degré d'un polynôme: c'est le plus grand degré tel que le coefficient correspondant est non nul, et il est borné par la longueur de la liste qui représente p
def deg(p):
d=0
# l'instruction suivante est une boucle for:
# elle exécute les instructions qui la suivent et qui sont décalées
# par rapport à elle,
# ceci pour chaque valeur de k dans la liste qui est donnée
# ici c'est range(len(p))
for k in range(len(p)):
if p[k]<>0: d=k # cette instruction est décalée par rapport à
# l'instruction for:
# elle est exécutée pour chaque valeur de k
return d # cette instruction n'est pas décalée par rapport à
# l'instruction for: elle est exécutée quand la boucle for
# est terminée
deg(p1)
deg(p2)
deg(p3)
# 2. Addition des polynômes
# pour calculer p+q, on additionne les coefficients de même degré
# cela correspond à additionner les termes de même rang des listes représentant
# les polynômes
def plus_poly(p,q):
# la variable res va contenir la liste représentant le polynôme somme
# de p et q, on va lui ajouter des éléments au fur et à mesure que l'on
# va calculer les sommes des coefficients de p et q, degré par degré
# au début elle est vide:
res=[]
# parcourons les deux listes p et q, degré par degré
# du degré 0 au degré maximum, qui est max(deg(p),deg(q))
# ne pas oublier le range(n) se termine avec n-1 et pas n
for k in range(max(deg(p),deg(q))+1):
res=res+[coef(p,k)+coef(q,k)]
return res
plus_poly(p1,p3)
# plus concis:
# une expression [f(k) for k in A] va calculer la liste des valeurs de f(k)
# pour chaque k de la liste A
def plus_poly(p,q):
return [coef(p,k)+coef(q,k) for k in range(max(deg(p),deg(q))+1)]
plus_poly(p1,p3)
# 3. Affichage des polynômes
# voir un polynôme sous sa forme en liste n'est pas très parlant,
# on va programmer qui affiche un polynôme comme on en a l'habitude en maths
# nous aurons besoin de fonctions d'une des bibliothèques python
import sys
# on définit une fonction qui imprime à l'écran une suite de caractères
# (on dit <<chaîne>> en informatique, sans le retour à la ligne que met
# la fonction standard print
def imprime_chaine(s):
sys.stdout.write(s)
# et d'une fonction qui fait demême avec un nombre
# pour cela on convertit le nombre en chaîne avec la fonction str
def imprime_nombre(x):
imprime_chaine(str(x))
# allons-y
def imprime_poly(p):
deja=False # pour savoir si on déjà imprimé quelque-chose du polynôme
for k in range(deg(p)+1):
c=coef(p,k)
if c<>0: # toutes les instructions jusqu'à l'instruction deja=True
# sont décalées: elles sont donc exécutées si c<>0
# celles d'après ne le sont plus donc sont exécutée
# indépendamment de la valeur de c
if c>0:
if deja: imprime_chaine('+')
else: imprime_chaine('-')
c=abs(c)
if c<>1 or k==0: imprime_nombre(c)
if k>=1: imprime_chaine('X')
if k>1:
imprime_chaine('^')
imprime_nombre(k)
deja=True
# fin de la boucle for, car il n'y a plus de décalage
# par rapport à l'instruction for
if deja==False: imprime_nombre('0')
imprime_chaine('\n')
imprime_poly(p1)
imprime_poly(p3)
imprime_poly([])
imprime_poly([0,-1])
# 4. Multiplication
# 4.1. Multiplication par une constante a
def mult_constante(a,p):
return [a*coef(p,k) for k in range(deg(p)+1)]
# 4.2. Multiplication par un monôme X^d
def mult_monome(p,d):
return ([0 for k in range(d)]+p)
# 4.2. Mutiplication des polynômes
def mult_poly(p,q):
res=[]
for k in range(deg(p)+1):
res=plus_poly(res,
mult_constante(coef(p,k),
mult_monome(q,k)))
return res
p4=[1,1]
imprime_poly(p4)
imprime_poly(mult_poly(p4,p4))
# 4.4. Puissances d'un polynôme
def puis_poly(p,n):
if n==0: return [1]
else: return mult_poly(p,puis_poly(p,n-1))
for n in range(13):
imprime_poly(puis_poly(p4,n))
imprime_poly(puis_poly(p4,500))
(pour l'enseigner l'an prochain, par exemple)
dimanche 10 février 2013
samedi 9 février 2013
leçon 1: départ, nombres entiers et algorithme d'Euclide
Je travaille dans l'environnement cygwin sous Windows, python (version 2) y est par défaut, et j'édite mes fichiers python avec emacs.
Sinon, python (version 2) s'installe sous windows 7: ici. Lancer IDLE (Python GUI).
Le fichier python contenant ce qui suit est là.
sh-4.1$ python
Python 2.7.3 (default, Dec 18 2012, 13:50:09)
[GCC 4.5.3] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
# Tout ce qui est après un dièse est considéré par python
# comme un commentaire, donc ignoré
# L'algorithme d'Euclide
# 1. La division euclidienne
# 1.1. Le quotient
# on définit une fonction quotient qui prend deux arguments a et b (1ere ligne)
# puis on teste la condition logique a<b (ligne 2)
# si la condition est vérifiée, alors on exécute ce qui suit les 2 points,
# qui consiste à donner la valeur dans cas de quotient(a,b) (ligne 3)
# si la condition n'est pas vérifiée, on exécute ce qui suit
# le mot-clé else (ligne 4): le résultat est obtenu en calculant
# la fonction quotient pour les arguments a-b et b.
# Il s'agit d'un calcul récursif, comme lorsque l'on définit une
# suite par récurrence: u_n+1 = f(u_n).
# pour exécuter la définition de la fonction qui suit, la copier
# et la coller sur la ligne de commande de python, puis finir par
# un retour chariot (Entrée)
def quotient(a,b):
if a<b: return 0
else: return 1+quotient(a-b,b)
quotient(7,2)
# les entiers de python ne sont pas bornés
quotient(500000000000000000000000000000,21111111111111111111111111111)
quotient(-7,2)
# problème, on a pas traité les nombre négatifs, redéfinissons la fonction
def quotient(a,b):
if a<0: return - quotient(-a,b)
elif b<0: return - quotient(a,-b)
elif a<b: return 0
else: return 1+quotient(a-b,b)
quotient(7,2)
quotient(-7,2)
quotient(7,-2)
quotient(-7,-2)
# remarquer les tests successifs:
# if ...:... elif ...:... elif ...:... else:...
# 1.2. Le reste
def reste(a,b):
return a-b*quotient(a,b)
reste(7,2)
reste(-7,2)
reste(7,-2)
reste(-7,-2)
# cette définition du reste et du quotient pour les nombres négatifs n'est pas la seule possible...
# 2. L'algorithme d'Euclide
# il consiste à diviser a par b, ce qui donne un reste b1,
# s'il est non nul on divise b par b1, ce qui donne un reste b2,
# puis ainsi de suite jusqu'à arriver à un reste nul.
# Le dernier reste non nul est alors le pgcd de a et b.
def pgcd(a,b):
if b==0: return a
else: return pgcd(b,reste(a,b))
pgcd(6,4)
pgcd(24,15)
pgcd(24543543543,155435434)
# on peut, en se servant des quotients dans cet algorithme,
# calculer les coefficients de Bezout u et v tels que
# u a + v b = pgcd(a,b)
# le resultat de cette fonction est une liste à deux éléments uv=[u,v]
# on accède au premier par la syntaxe uv[0] et au second par uv[1]
def bezout(a,b):
if b==0: return [1,0]
else:
uv= bezout(b,reste(a,b))
return [uv[1],uv[0]-uv[1]*quotient(a,b)]
bezout(3,4)
bezout(8,5)
# 3. Un exemple avec la suite de Fibonacci
# on définit cette suite par
# f_0 = 0 et f_1 = 1, f_n+2 = f_n+1 + f_n
# posons fib(n) = f_n
def fib(n):
if n==0: return 0
elif n==1: return 1
else: return fib(n-1)+fib(n-2)
fib(10)
# le pgcd de f_a et f_b est f_c où c est le pgcd de a et b
pgcd(fib(18),fib(27))
fib(9)
Sinon, python (version 2) s'installe sous windows 7: ici. Lancer IDLE (Python GUI).
Le fichier python contenant ce qui suit est là.
sh-4.1$ python
Python 2.7.3 (default, Dec 18 2012, 13:50:09)
[GCC 4.5.3] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
# Tout ce qui est après un dièse est considéré par python
# comme un commentaire, donc ignoré
# L'algorithme d'Euclide
# 1. La division euclidienne
# 1.1. Le quotient
# on définit une fonction quotient qui prend deux arguments a et b (1ere ligne)
# puis on teste la condition logique a<b (ligne 2)
# si la condition est vérifiée, alors on exécute ce qui suit les 2 points,
# qui consiste à donner la valeur dans cas de quotient(a,b) (ligne 3)
# si la condition n'est pas vérifiée, on exécute ce qui suit
# le mot-clé else (ligne 4): le résultat est obtenu en calculant
# la fonction quotient pour les arguments a-b et b.
# Il s'agit d'un calcul récursif, comme lorsque l'on définit une
# suite par récurrence: u_n+1 = f(u_n).
# pour exécuter la définition de la fonction qui suit, la copier
# et la coller sur la ligne de commande de python, puis finir par
# un retour chariot (Entrée)
def quotient(a,b):
if a<b: return 0
else: return 1+quotient(a-b,b)
quotient(7,2)
# les entiers de python ne sont pas bornés
quotient(500000000000000000000000000000,21111111111111111111111111111)
quotient(-7,2)
# problème, on a pas traité les nombre négatifs, redéfinissons la fonction
def quotient(a,b):
if a<0: return - quotient(-a,b)
elif b<0: return - quotient(a,-b)
elif a<b: return 0
else: return 1+quotient(a-b,b)
quotient(7,2)
quotient(-7,2)
quotient(7,-2)
quotient(-7,-2)
# remarquer les tests successifs:
# if ...:... elif ...:... elif ...:... else:...
# 1.2. Le reste
def reste(a,b):
return a-b*quotient(a,b)
reste(7,2)
reste(-7,2)
reste(7,-2)
reste(-7,-2)
# cette définition du reste et du quotient pour les nombres négatifs n'est pas la seule possible...
# 2. L'algorithme d'Euclide
# il consiste à diviser a par b, ce qui donne un reste b1,
# s'il est non nul on divise b par b1, ce qui donne un reste b2,
# puis ainsi de suite jusqu'à arriver à un reste nul.
# Le dernier reste non nul est alors le pgcd de a et b.
def pgcd(a,b):
if b==0: return a
else: return pgcd(b,reste(a,b))
pgcd(6,4)
pgcd(24,15)
pgcd(24543543543,155435434)
# on peut, en se servant des quotients dans cet algorithme,
# calculer les coefficients de Bezout u et v tels que
# u a + v b = pgcd(a,b)
# le resultat de cette fonction est une liste à deux éléments uv=[u,v]
# on accède au premier par la syntaxe uv[0] et au second par uv[1]
def bezout(a,b):
if b==0: return [1,0]
else:
uv= bezout(b,reste(a,b))
return [uv[1],uv[0]-uv[1]*quotient(a,b)]
bezout(3,4)
bezout(8,5)
# 3. Un exemple avec la suite de Fibonacci
# on définit cette suite par
# f_0 = 0 et f_1 = 1, f_n+2 = f_n+1 + f_n
# posons fib(n) = f_n
def fib(n):
if n==0: return 0
elif n==1: return 1
else: return fib(n-1)+fib(n-2)
fib(10)
# le pgcd de f_a et f_b est f_c où c est le pgcd de a et b
pgcd(fib(18),fib(27))
fib(9)
Exercices:
1. programmer une fonction qui calcule la factorielle d'un entier n
2. programmer une fonction qui calcule la suite de Collatz:
si $u_n$ est pair, $u_{n+1} = \cfrac {u_n} 2$, sinon $u_{n+1} = 3 u_n+1$.
1. programmer une fonction qui calcule la factorielle d'un entier n
2. programmer une fonction qui calcule la suite de Collatz:
si $u_n$ est pair, $u_{n+1} = \cfrac {u_n} 2$, sinon $u_{n+1} = 3 u_n+1$.
Inscription à :
Articles (Atom)