IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Mathématiques et Python - apprendre à créer une classe Polynome en Python avec la surcharge des opérateurs
Un billet blog de Denis Hulo

Le , par User

0PARTAGES

I. Introduction

Notre objectif est de créer une classe Polynome dans laquelle on redéfinira les opérateurs d'addition, de multiplication et de puissance pour les polynômes.


Nous ajouterons également à notre classe des méthodes permettant d'évaluer un polynôme ou de tracer la courbe représentant sa fonction polynomiale.

Rappel important :

La surcharge d’opérateur permet de redéfinir un opérateur dans une classe.

Par exemple, en Python l’opérateur « + » est surchargé par la classe int et la classe str :

  • On peut ainsi réaliser une addition classique entre deux entiers : print(1+2) affiche 3.
  • Ou concaténer deux chaînes de caractères : print("bon"+"jour") renvoie "bonjour".


II. Polynôme

II-A. Définition

En mathématiques, un polynôme de la variable x peut s'écrire sous la forme :

P(x) = a0 + a1x + ... + an-1xn-1 + anxn

x est une variable appelée indéterminée (dans notre cas un réel), les constantes a0, a1, ..., an sont les coefficients du polynôme et n est un entier naturel.

II-B. Opérations sur les polynômes

II-B-1. Addition

Soient 2 polynômes de la forme :

P1(x) = a0 + a1x + ... + an-1xn-1 + anxn
P2(x) = b0 + b1x + ... + bm-1xm-1 + bnxm

L'addition de ces 2 polynômes P1(x) et P2(x) donne pour n=m :

P1(x) + P2(x) = (a0 + b0) + (a1 + b1)x + ... + (an-1 + bn-1)xn-1 + (an + bn)xn

Et pour n>m :

P1(x) + P2(x) = (a0 + b0) + (a1 + b1)x + ... + (am-1 + bm-1)xm-1 + (am + bm)xm + ... + anxn

On additionne donc simplement les coefficients de même degré.

Note importante : on voit que suivant cette représentation les coefficients de même degré sont alignés l'un en dessous de l'autre.

II-B-2. Multiplication

Soient 2 polynômes de degré 1 :

P1(x) = a0 + a1x
P2(x) = b0 + b1x

La multiplication étant distributive par rapport à l'addition, le produit de ces 2 polynômes P1(x) et P2(x) nous donne :

P1(x) × P2(x) = (a0 + a1x)(b0 + b1x)
P1(x) × P2(x) = a0b0 + a0b1x + a1b0x + a1b1x2

On peut ainsi généraliser facilement ce résultat à des polynômes de degrés quelconques.

Pour avoir plus d'informations sur le sujet, je vous invite à consulter la page de wikipedia Polynôme formel.

II-C. Fonction polynomiale

En mathématiques, une fonction polynomiale (parfois appelée fonction polynôme) est une fonction obtenue en évaluant un polynôme.

Plus précisément, une fonction polynomiale f est définie sur un domaine Df par :

x → anxn + an-1xn-1 + ... + a1x + a0

x appartient à Df et a pour image f(x).

Une fonction polynomiale d'une variable réelle peut être représentée graphiquement.

III. Création de la classe Polynome

Pour définir ces polynômes en Python et pouvoir réaliser des opérations entre eux, il nous faut créer une classe Polynome.

Notre classe comportera un constructeur, c'est-à-dire une méthode particulière __init__() dont le code est exécuté quand la classe est instanciée.

Elle va nous permettre de définir la liste des coefficients du polynôme au moment de la création de l'objet :

Code Python : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Polynome: 
  
    def __init__(self, liste_coefs=[0]): # méthode constructeur de la classe 
  
        self.coefs = liste_coefs # on définit la liste des coefficients du polynôme [a0, a1, ..., an] 
        self.reduire() # suppression si nécessaire des zéros en queue de liste de coefficients. Exemple : [2, 3, 1, 0, 0] -> [2, 3, 1] 
  
    def __str__(self): # permet d'afficher le polynôme sous la forme 1 + 2x + 3x^2 
        s="" # initialisation de la chaîne de caractères 
        # on vérifie d’abord si le degré du polynôme est nul 
        if (len(self.coefs)-1==0): 
            return str(self.coefs[0]) 
        else: # sinon 
            if self.coefs[0]!=0: 
                s=str(self.coefs[0]) + " + " 
            for i in range(1, len(self.coefs)): # parcours des indices des coefficients du polynôme : [a1, a2, ..., an] 
                if self.coefs[i]!=0: # si le coefficient de degré i n'est pas nul 
                    if self.coefs[i]!=1: # si le coefficient de degré i est différent de 1 
                        s+="{}.X^{} + ".format(self.coefs[i],i) 
                    else: s+="X^{} + ".format(i)       
            return s[:-3] # on retourne l'expression du polynôme

La méthode __str__ permet d'afficher un polynôme sous la forme 1 + 2.x^1 + x^2.

Pour tester ces méthodes, nous ajoutons simplement deux lignes au module :

Code Python : Sélectionner tout
1
2
p = Polynome([1, 2, 1]) # création de l'objet Polynome : 1 + 2x + x^2 
print(p) # affiche l'expression du polynôme

Le code affiche :

1 + 2.x^1 + x^2

Note importante : la liste de coefficients permettant de créer l'objet Polynome contient également les coefficients nuls.

Par exemple, le polynôme P(x) = x^2 + 2.x^4 sera représenté par la liste [0, 0, 1, 0, 2] .

III-A. Surcharge de l'opérateur d'addition

Pour surcharger l'opérateur « + » et pouvoir ainsi réaliser l'addition de 2 polynômes, nous devons ajouter une méthode __add __ () à la classe :

Code Python : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
class Polynome: 
    ...  
    def __add__(self, other): # méthode permettant de redéfinir l'opérateur « + » pour 2 polynômes : (1 + 2x + x^2) + (1 + x) = 2 + 3x + x^2 
        # p1 = self, p2 = other      
        if len(other.coefs) >len(self.coefs): # si degré de p2 > degré de p1  
            liste_coefs = other.coefs[:]; n = len(self.coefs) # on copie les coefs du polynôme de degré le plus élevé et la longueur de la liste de coefs la plus petite.  
        else: liste_coefs = self.coefs[:]; n = len(other.coefs) # sinon, ... 
  
        for i in range(n): # parcours des indices de liste_coefs 
            liste_coefs[i] = self.coefs[i] + other.coefs[i] # addition des coefficients de degré i 
  
        return Polynome(liste_coefs) # renvoie le polynôme résultat de l'addition

Cette méthode permet donc de redéfinir l'opération « + » pour les polynômes en additionnant les coefficients de même degré.

Pour tester l'opérateur d'addition portant sur 2 objets de la classe Polynome, nous ajoutons simplement ces lignes de code :

Code Python : Sélectionner tout
1
2
3
4
p1 = Polynome([1, 2, 1]) # création du 1er objet de la classe Polynome : 1 + 2x + x^2 
p2 = Polynome([1, 1]) # création du 2e objet Polynome : 1 + x 
  
print(p1+p2) # affiche le résultat de l'addition

Le code affiche :

2 + 3.x^1 + x^2

III.B. Surcharge de l'opérateur de multiplication

Pour surcharger l'opérateur « * » et l'appliquer à 2 polynômes, nous devons également ajouter une méthode __mul __ () à la classe :

Code Python : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
class Polynome: 
    ...  
    def __mul__(self, other): # méthode permettant de redéfinir l'opérateur « * » pour 2 polynômes : (1 + x) * (1 + 2x) =  1 + 3x + 2x^2 
        # initialisation de la liste des coefficients qu'avec des zéros 
        liste_coefs=[0]*(len(self.coefs)+len(other.coefs)-1) # exemple : [0, 0, 0] 
        for i1 in range(len(self.coefs)): # parcours des indices des coefs du polynôme n°1 
            for i2 in range(len(other.coefs)): # parcours des indices des coefs du polynôme n°2 
                # multiplication des coefficients d'indices i1 et i2 
                liste_coefs[i1+i2] = liste_coefs[i1+i2] + self.coefs[i1]*other.coefs[i2] 
  
        poly=Polynome(liste_coefs) # création de l'objet Polynome basé sur la liste 
  
        return poly # renvoie le polynôme résultat de la multiplication

Cette méthode permet donc de redéfinir l'opération de multiplication pour 2 polynômes en utilisant la propriété de distributivité de la multiplication par rapport à l'addition.

Pour tester l'opérateur de multiplication portant sur 2 objets de la classe Polynome, nous ajoutons simplement ces lignes :

Code Python : Sélectionner tout
1
2
3
4
p1 = Polynome([1, 1]) # création du 1er objet de la classe Polynome : 1 + x 
p2 = Polynome([1, 2]) # création du 2e objet de la classe Polynome : 1 + 2x 
  
print(p1*p2) # affiche le résultat du produit de p1 par p2

Le code affiche :

1 + 3.X^1 + 2.X^2

III-C. Surcharge de l'opérateur de puissance

Maintenant que nous avons redéfini les opérateurs d'addition et de multiplication dans notre classe Polynome, nous pouvons ajouter une méthode __pow__() qui va permettre d'obtenir le résultat d'un polynôme élevé à la puissance n.

Code Python : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
class Polynome: 
    ...	 
    def __pow__(self, n): # méthode permettant de redéfinir l'opérateur de puissance : self ** n 
        # on crée l'objet poly à partir d'une liste contenant un seul élément 1, élément neutre pour la multiplication des polynômes 
        poly = Polynome([1])  
  
        for i in range(n): # on multiplie n fois poly par self à l'aide de l'opérateur *             
            poly = poly*self # équivalent à : poly = poly.__mul__(self) 
  
        return poly # renvoie le polynôme résultat de l'opération (self ** n)

Nous testons maintenant l'opérateur pour (1 + x) ** 3 :

Code Python : Sélectionner tout
1
2
p = Polynome([1, 1]) 
print(p**3)

Le code renvoie :

1 + 3.X^1 + 3.X^2 + X^3

Vérification

p3 = (1 + x)3
p3 = (1 + x)(1 + x)(1 + x)

En développant et en réduisant le produit des 2 premiers facteurs, on obtient :

p3 = (1 + 2x + x2)(1 + x)

Enfin, en développant et en réduisant une seconde fois, on a bien :

p3 = 1 + 3.X^1 + 3.X^2 + X^3

Tableau de quelques opérateurs et de leur méthode correspondante en Python :

Opérateur Expression Interprétation Python
Addition p1 + p2 p1.__add__(p2)
Soustraction p1 - p2 p1.__sub__(p2)
Multiplication p1 * p2 p1.__mul__(p2)
Puissance p1 ** n p1.__pow__(n)
Division p1 / p2 p1.__truediv__(p2)
Division entière p1 // p2 p1.__floordiv__(p2)
Modulo p1 % p2 p1.__mod__(p2)
... ... ...
III-D. Surcharge de l'opérateur de comparaison « == »

Pour surcharger l'opérateur « == » et pouvoir ainsi tester si 2 polynômes sont égaux, nous ajoutons une méthode __eq__ () à notre classe :

Code Python : Sélectionner tout
1
2
3
4
5
class Polynome: 
    ... 
    def __eq__(poly1, poly2): # méthode permettant de redéfinir l'opérateur « == » pour 2 polynômes 
  
        return (poly1.coefs==poly2.coefs) # renvoie True si les 2 liste de coefficients sont égales

Cette méthode permet donc de redéfinir l'opérateur de comparaison « == » pour deux polynômes en testant si leurs coefficients sont égaux :

Code Python : Sélectionner tout
1
2
3
4
p1 = Polynome([1, 2]) # création du 1er objet de la classe Polynome : 1 + 2x 
p2 = Polynome([1, 2]) # création du 2e objet Polynome : 1 + 2x 
  
print(p1==p2) # affiche le résultat de la comparaison

Le code affiche :

True

Tableau de quelques opérateurs de comparaison et de leur méthode correspondante en Python :

Opérateur Expression Interprétation Python
Inférieur à p1 < p2 p1.__lt__(p2)
Inférieur ou égal p1 <= p2 p1.__le__(p2)
Egal p1 == p2 p1.__eq__(p2)
... ... ...
Si vous souhaitez avoir une liste plus complète des opérateurs, je vous invite à consulter cette page.

III-E. Evaluation du polynôme

Déterminons la valeur d'un polynôme en se basant sur l'expression :

P(x) = a0 + a1x + ... + an-1xn-1 + anxn

Nous ajoutons pour cela une méthode eval() à notre classe :

Code Python : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
class Polynome: 
    ... 
    def eval(self,x): # méthode permettant d'évaluer le polynôme en fonction de x 
        # intialisation des variables 
        valeur_polynome = self.coefs[0] # valeur_polynome = a0 
        power=1     
  
        for coef in self.coefs[1:]: # parcours des coefficients du polynôme à partir de a1 : a1, a2, ..., an 
            power = power*x # calcul de la puissance de x pour ai : power = x^i 
            valeur_polynome += coef*power # valeur_polynome = valeur_polynome + ai*x^i 
  
        return valeur_polynome # renvoie la valeur du polynôme
Code Python : Sélectionner tout
1
2
3
p = Polynome([1, 1, 2]) # création de l'objet de la classe Polynome : 1 + x + 2x^2 
  
print(p.eval(10)) # affiche la valeur du polynôme pour x=10

Le code affiche :

211

Note importante : dans ce cas nous avons besoin au mieux de 2n-1 multiplications pour évaluer notre polynôme.

Nous pouvons également évaluer notre polynôme avec seulement n multiplications en utilisant le schéma de Horner suivant :

P(x) = ((...((anx + an-1)x + an-2)x + ...)x + a1)x + a0

La méthode eval_horner() basée sur ce schéma :

Code Python : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
class Polynome: 
    ... 
    def eval_horner(self,x): # méthode permettant d'évaluer le polynôme en fonction de x 
        # intialisation de la variable 
        valeur_polynome = self.coefs[-1] # valeur_polynome = an 
  
        for coef in reversed(self.coefs[:-1]): # parcours des coefficients du polynôme à partir de an-1 : an-1, ..., a1, a0 
            valeur_polynome = valeur_polynome*x + coef  # valeur_polynome = valeur_polynome*x + ai 
  
        return valeur_polynome # renvoie la valeur du polynôme


A noter qu'il existe également dans numpy des classes poly1d et Polynomial permettant de créer des objets Polynome.

III-F. Fonction polynomiale : représentation graphique

Nous souhaitons maintenant ajouter à notre classe Polynome un attribut permettant de représenter le domaine de définition de la fonction polynomiale et une méthode pour tracer sa courbe représentative.



III-F.1 Attribut domaine

Nous ajoutons donc à notre méthode __init__() un argument optionnel domaine représentant le domaine de définition de la fonction polynomiale :

Code Python : Sélectionner tout
1
2
3
4
5
6
7
8
class Polynome: 
  
    def __init__(self, liste_coefs=[0], domaine=None): # méthode constructeur de la classe 
  
        self.coefs = liste_coefs # on définit la liste des coefficients du polynôme [a0, a1, ..., an] 
        self.reduire() # suppression si nécessaire des zéros en queue de liste de coefficients. Exemple : [2, 3, 1, 0, 0] -> [2, 3, 1] 
  
        self.domaine = domaine # on définit l'intervalle [x0, xn] représentant le domaine de définition de la fonction


III-F.2 Représentation graphique de la fonction polynomiale

Nous souhaitons maintenant tracer la courbe représentative de la fonction polynomiale.

Pour cela, nous avons d'abord besoin d'importer le module pyplot de la librairie matplotlib pour disposer des fonctions permettant de tracer une courbe à l'écran :

Code Python : Sélectionner tout
1
2
import matplotlib.pyplot as plt # module permettant de générer le graphique 
...

Puis, nous aimerions utiliser notre objet Polynome comme une fonction. Nous ajoutons ainsi une méthode __call__ à notre classe :

Code Python : Sélectionner tout
1
2
3
4
class Polynome: 
    ... 
  def __call__ (self, x): # permet d'appeler la fonction eval() en faisant f(2) au lieu de f.eval(2) 
        return self.eval(x)

Elle va permettre d'appeler la fonction eval() de l'objet Polynome f en faisant simplement :

Code Python : Sélectionner tout
valeur = f(2)

Au lieu de :

Code Python : Sélectionner tout
valeur = f.eval(2)

Enfin, nous ajoutons une méthode tracer() :

Code Python : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Polynome: 
    ... 
    def tracer(self, x0=None, xn=None, pas=0.1): # trace la courbe représentant la fonction polynomiale sur l'intervalle [x0, xn] 
  
        if x0==None and xn==None: # si les arguments x0 et xn sont ommis, on trace la courbe sur l'intervalle correspondant au domaine de définition 
            if self.domaine!=None: # si le domaine de la fonction est défini 
                x0 = self.domaine[0]; xn = self.domaine[1] 
            else: print("Pas de domaine de définition pour la fonction !"); return  
  
        # on crée la liste des valeurs d'abscisse entre x0 et xn  
        x = np.arange(x0, xn, pas) # appel de la fonction arange de la librairie numpy  
  
        # on crée la liste des yi en évaluant la fonction polynomiale pour chaque xi : self(xi) est équivalent à self.eval(xi) 
        y = [self(xi) for xi in x] 
  
        # trace la courbe qui relie les points dont les abscisses x et les ordonnées y sont fournies en arguments.  
        plt.plot(x, y) 
        plt.title('f(x) = '  + self.expr_fonc()) # copie du titre du graphique 
        plt.show() # affiche la figure à l'écran


Testons le code :

Code Python : Sélectionner tout
1
2
3
4
5
6
7
8
domaine_definition = [-5, 5] # intervalle représentant le domaine de définition de la fonction 
  
f = Polynome([2, 1, 2], domaine_definition) # création de l'objet Polynome à partir de la liste de coefficients [2, 1, 2] et du domaine de définition de la fonction 
  
print(f(2)) # affiche la valeur de la fonction pour x=2 
  
# trace la courbe représentant la fonction polynomiale sur l'intervalle [-5, 5] avec un pas de 0.1 
f.tracer()

Le code affiche :

12

Puis le graphique :



Module complet contenant la classe Polynome :

Code Python : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
import numpy as np # module permettant de disposer de la fonction arange 
import matplotlib.pyplot as plt # module permettant de générer le graphique 
  
class Polynome: 
  
    def __init__(self, liste_coefs=[0], domaine=None): # méthode constructeur de la classe 
  
        self.coefs = liste_coefs # on définit la liste des coefficients du polynôme [a0, a1, ..., an] 
        self.reduire() # suppression si nécessaire des zéros en queue de liste de coefficients. Exemple : [2, 3, 1, 0, 0] -> [2, 3, 1] 
  
        self.domaine = domaine # on définit l'intervalle [x0, xn] représentant le domaine de définition de la fonction 
  
    def __str__(self): # permet d'afficher le polynôme sous la forme 1 + 2x + 3x^2 
        s="" # initialisation de la chaîne de caractères 
        # on vérifie d’abord si le degré du polynôme est nul 
        if (len(self.coefs)-1==0): 
            return str(self.coefs[0]) 
        else: # sinon 
            if self.coefs[0]!=0: 
                s=str(self.coefs[0]) + " + " 
            for i in range(1, len(self.coefs)): # parcours des indices des coefficients du polynôme : [a1, a2, ..., an] 
                if self.coefs[i]!=0: # si le coefficient de degré i n'est pas nul 
                    if self.coefs[i]!=1: # si le coefficient de degré i est différent de 1 
                        s+="{}.X^{} + ".format(self.coefs[i],i) 
                    else: s+="X^{} + ".format(i)       
            return s[:-3] # on retourne l'expression du polynôme 
  
    def eval_degre(self): # retourne le degré du polynôme 
        return (len(self.coefs)-1) 
  
    def __add__(self, other): # méthode permettant de redéfinir l'opérateur « + » pour 2 polynômes : (1 + 2x + x^2) + (1 + x) = 2 + 3x + x^2 
        # p1 = self, p2 = other      
        if len(other.coefs) >len(self.coefs): # si degré de p2 > degré de p1  
            liste_coefs = other.coefs[:]; n = len(self.coefs) # on copie les coefs du polynôme de degré le plus élevé et la longueur de la liste de coefs la plus petite.  
        else: liste_coefs = self.coefs[:]; n = len(other.coefs) # sinon, ... 
  
        for i in range(n): # parcours des indices de liste_coefs 
            liste_coefs[i] = self.coefs[i] + other.coefs[i] # addition des coefficients de degré i 
  
        return Polynome(liste_coefs,self.domaine) # renvoie le polynôme résultat de l'addition 
  
    def reduire(self): 
        # tant que le dernier élément de la liste est nul 
       while self.coefs[-1] == 0 and len(self.coefs)>1: 
            self.coefs.pop() # supprimer le dernier élément 
  
    def __mul__(self, other): # méthode permettant de redéfinir l'opérateur « * » pour 2 polynômes : (1 + x) * (1 + 2x) =  1 + 3x + 2x^2 
        # initialisation de la liste des coefficients qu'avec des zéros 
        liste_coefs=[0]*(len(self.coefs)+len(other.coefs)-1) # exemple : [0, 0, 0] 
        for i1 in range(len(self.coefs)): # parcours des indices des coefs du polynôme n°1 
            for i2 in range(len(other.coefs)): # parcours des indices des coefs du polynôme n°2 
                # multiplication des coefficients d'indices i1 et i2 
                liste_coefs[i1+i2] = liste_coefs[i1+i2] + self.coefs[i1]*other.coefs[i2] 
  
        poly=Polynome(liste_coefs, self.domaine) # création de l'objet Polynome basé sur la liste 
  
        return poly # renvoie le polynôme résultat de la multiplication 
  
    def __pow__(self, n): # méthode permettant de redéfinir l'opérateur de puissance : self ** n 
        # on crée l'objet poly à partir d'une liste contenant un seul élément 1, élément neutre pour la multiplication des polynômes 
        poly = Polynome([1],self.domaine)  
  
        for i in range(n): # on multiplie n fois poly par self à l'aide de l'opérateur *             
            poly = poly*self # équivalent à : poly = poly.__mul__(self) 
  
        return poly # renvoie le polynôme résultat de l'opération (self ** n) 
  
    def __eq__(poly1, other): # méthode permettant de redéfinir l'opérateur « == » pour 2 polynômes 
  
        return (poly1.coefs==other.coefs) # renvoie True si les 2 liste de coefficients sont égales 
  
    def eval(self,x): # méthode permettant d'évaluer le polynôme en fonction de x 
        # intialisation des variables 
        valeur_polynome = self.coefs[0] # valeur_polynome = a0 
        power=1     
  
        for coef in self.coefs[1:]: # parcours des coefficients du polynôme à partir de a1 : a1, a2, ..., an 
            power = power*x # calcul de la puissance de x pour ai : power = x^i 
            valeur_polynome += coef*power # valeur_polynome = valeur_polynome + ai*x^i 
  
        return valeur_polynome # renvoie la valeur du polynôme 
  
    def eval_horner(self,x): # méthode permettant d'évaluer le polynôme en fonction de x 
        # intialisation de la variable 
        valeur_polynome = self.coefs[-1] # valeur_polynome = an 
  
        for coef in reversed(self.coefs[:-1]): # parcours des coefficients du polynôme à partir de an-1 : an-1, ..., a1, a0 
            valeur_polynome = valeur_polynome*x + coef  # valeur_polynome = valeur_polynome*x + ai 
  
        return valeur_polynome # renvoie la valeur du polynôme 
  
    # Fonction polynomial 
  
    def expr_fonc(self): # affiche le polynôme sous la forme 1 + 2x + 3x^2 
        s="" # initialisation de la chaîne de caractères 
        # on vérifie d’abord si le degré du polynôme est nul 
        if (len(self.coefs)-1==0): 
            return str(self.coefs[0]) 
        else: # sinon 
            for i in range(len(self.coefs)-1,0,-1): # parcours des indices des coefficients du polynôme : [a1, a2, ..., an] 
                if self.coefs[i]!=0: # si le coefficient de degré i n'est pas nul 
                    if self.coefs[i]!=1: # si le coefficient de degré i est différent de 1 
                        s+="{}.x^{} + ".format(self.coefs[i],i) 
                    else: s+="x^{} + ".format(i) 
  
            if self.coefs[0]!=0: 
                s+=str(self.coefs[0]) + " + " 
  
            return s[:-3] # on retourne l'expression du polynôme 
  
    def __call__ (self, x): # permet d'appeler la fonction eval() en faisant f(2) au lieu de f.eval(2) 
        return self.eval(x) 
  
    def tracer(self, x0=None, xn=None, pas=0.1): # trace la courbe représentant la fonction polynomiale sur l'intervalle [x0, xn] 
  
        if x0==None and xn==None: # si les arguments x0 et xn sont ommis, on trace la courbe sur l'intervalle correspondant au domaine de définition 
            if self.domaine!=None: # si le domaine de la fonction est défini 
                x0 = self.domaine[0]; xn = self.domaine[1] 
            else: print("Pas de domaine de définition pour la fonction !"); return  
  
        # on crée la liste des valeurs d'abscisse entre x0 et xn  
        x = np.arange(x0, xn, pas) # appel de la fonction arange de la librairie numpy  
  
        # on crée la liste des yi en évaluant la fonction polynomiale pour chaque xi : self(xi) est équivalent à self.eval(xi) 
        y = [self(xi) for xi in x] 
  
        # trace la courbe qui relie les points dont les abscisses x et les ordonnées y sont fournies en arguments.  
        plt.plot(x, y) 
        plt.title('f(x) = '  + self.expr_fonc()) # copie du titre du graphique 
        plt.show() # affiche la figure à l'écran 
  
    def deriver(self): # renvoie la dérivée de la fonction polynomiale f(x) 
        # initialisation de la liste des coefficients qu'avec des zéros 
        liste_coefs=[0]*len(self.coefs) # exemple : [0, 0, 0, 0, 0] 
        for i in range(len(self.coefs)-1): 
            liste_coefs[i] = self.coefs[i+1]*(i+1) 
  
        return Polynome(liste_coefs, self.domaine) 
  
  
# addition de 2 polynômes 
  
p1 = Polynome([1, 2, 1]) # création du 1er objet de la classe Polynome : 1 + 2x + x^2 
p2 = Polynome([1, 1]) # création du 2e objet Polynome : 1 + x 
  
print(p1+p2) # affiche le résultat de l'addition de p1 et p2 
  
# multiplication de 2 polynômes 
  
p1 = Polynome([1, 1]) # création du 1er objet de la classe Polynome : 1 + x 
p2 = Polynome([1, 2]) # création du 2e objet de la classe Polynome : 1 + 2x 
  
print(p1*p2) # affiche le résultat de la multiplication de p1 par p2 
  
# élévation à la puissance d'un polynôme 
  
print(p1**3) # affiche le résultat de p1 à la puissance 3 
  
# création d'un objet fonction polynomiale 
  
domaine_definition = [-5, 5] # intervalle représentant le domaine de définition de la fonction 
  
f = Polynome([2, 1, 2], domaine_definition) # création de l'objet Polynome à partir de la liste de coefficients [2, 1, 2] et du domaine de définition de la fonction 
  
print(f(2)) # affiche la valeur de la fonction polynomiale pour x=2 
  
# trace la courbe représentant la fonction polynomiale sur l'intervalle [-5, 5] avec un pas de 0.1 
f.tracer()


IV. Conclusion

Après avoir défini les opérations d'addition et de multiplication pour les polynômes, nous avons pu redéfinir les opérateurs « + », « * » et « ** » dans une classe Python à l'aide de la surcharge d'opérateurs.

Puis, nous avons ajouté à notre classe des méthodes permettant d'évaluer un polynôme ou de tracer sa courbe représentative.

Chacun pourra ensuite librement ajouter d'autres méthodes à cette classe, ou bien en créer une autre pour représenter par exemple un polynôme trigonométrique.

Sources :

https://fr.wikipedia.org/wiki/Polyn%C3%B4me
https://fr.wikipedia.org/wiki/Polyn%C3%B4me_formel
https://fr.wikipedia.org/wiki/Fonction_polynomiale
https://en.wikipedia.org/wiki/Polynomial
https://python.developpez.com/tutori...s/?page=classe
https://allen-downey.developpez.com/...methodes#L17-7
https://docs.python.org/fr/3/library/operator.html

Une erreur dans cette actualité ? Signalez-nous-la !