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

Surcharge des opérateurs en Python

Objectif : redéfinir dans une classe Python les opérateurs d'addition, de multiplication et de puissance pour les nombres complexes.

Niveau requis : débutant.

Commentez cet article : 11 commentaires Donner une note à l´article (5)

Article lu   fois.

L'auteur

Profil Pro

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Introduction

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".

Notre objectif est de redéfinir dans une classe Pythonune classe Python les opérateurs d'addition, de multiplication et de puissance pour les nombres complexesnombres complexes.

II. Nombres complexes

II-A. Définition

En mathématiques, l'ensemble des nombres complexes est créé comme extension de l'ensemble des nombres réels, contenant en particulier un nombre imaginaire noté i, tel que i2 = −1. Le carré de (−i) est aussi égal à −1 : (−i)2 = −1.

Tout nombre complexe peut s'écrire sous la forme a + iba et b sont des nombres réels.

Représentation graphique du nombre complexe
Représentation graphique du nombre complexe

II-B. Représentation

II-B-1. Forme algébrique

Un nombre complexe z se présente en général sous forme algébrique comme une somme a + ib,
a et b sont des nombres réels quelconques
et où i (l’unité imaginaire) est un nombre particulier tel que i2 = –1.

II-B-2. Forme trigonométrique

Pour tout couple de réels (a, b) différent du couple (0,0), il existe un réel positif r et une famille d'angles θ déterminés à un multiple de 2π près tels que a = r cos(θ) et b = r sin(θ).

Tout nombre complexe non nul peut donc s'écrire sous une forme trigonométrique :
z = r (cos(θ) + i sin(θ)) avec r > 0.

Le réel positif r est appelé le module du complexe z et il est noté |z|. Le réel θ est appelé un argument du complexe z et il est noté arg(z).

II-B-3. Opérations sur les nombres complexes

II-B-3-a. Addition

L'addition de 2 nombres complexes z1 = a + ib et z2 = c + id écrits sous forme algébrique, est définie par :

(a + ib) + (c + id) = (a+b) + i(b+d)

II-B-3-b. Multiplication

La multiplication de 2 nombres complexes z1 = a + ib et z2 = c + id écrits sous forme algébrique, est définie par :

(a + ib) × (c + id) = (ac - bd) + i(ad + bc)

Pour avoir plus d'informations sur le sujet, je vous invite à consulter la page de Wikipedia Nombre complexeNombre complexe.

III. Création de la classe Complexe

Pour définir ces nombres complexes en Python et pouvoir réaliser des opérations entre eux, il nous faut créer une classeclasse Complexe.

Notre classe comportera un constructeurconstructeur, 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 les parties réelle et imaginaire du nombre complexe au moment de la création de l'objet :

 
Sélectionnez
class Complexe:
 
    def __init__(self, part_reel=0, part_imag=0): # méthode constructeur de la classe
        self.reel = part_reel # on définit la partie réelle du nombre complexe
        self.imag = part_imag # on définit la partie imaginaire du nombre complexe
 
    def __str__(self): # permet d'afficher le nombre complexe sous la forme algébrique a + bi
        return "{0} + {1}i".format(self.reel, self.imag) if self.imag>=0 else "{0} - {1}i".format(self.reel, abs(self.imag))

La méthode __str__() permet d'afficher un nombre complexe sous la forme a + bi.

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

 
Sélectionnez
z = Complexe(1, 2) # création de l'objet Complexe : 1 + 2i
print(z) # affiche le nombre complexe

Le code affiche :

1 + 2i

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

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

 
Sélectionnez
class Complexe:
 
    def __init__(self, part_reel=0, part_imag=0): # méthode constructeur de la classe
        self.reel = part_reel # on définit la partie réelle du nombre complexe
        self.imag = part_imag # on définit la partie imaginaire du nombre complexe
 
    def __str__(self): # permet d'afficher le nombre complexe sous la forme algébrique a + bi
        return "{0} + {1}i".format(self.reel, self.imag) if self.imag>=0 else "{0} - {1}i".format(self.reel, abs(self.imag))
 
    def __add__(self, other): # méthode permettant de redéfinir l'opérateur « + » pour 2 nombres complexes : z1 + z2 = (a + bi) + (c + di) = (a+c) + (b+d)i 
        part_reel = self.reel + other.reel # on évalue la partie réelle du nombre complexe résultat de l'addition
        part_imag = self.imag + other.imag # on évalue la partie imaginaire du nombre complexe résultat de l'addition
        return Complexe(part_reel, part_imag) # renvoie le nombre complexe résultat de l'addition

Cette méthode permet donc de redéfinir l'opération « + » pour les nombres complexes en utilisant l'égalité :

(a + bi) + (c + di) = (a+c) + (b+d)i

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

 
Sélectionnez
z1 = Complexe(1, 2) # création du 1er objet de la classe Complexe : 1 + 2i
z2 = Complexe(2, 3) # création du 2e objet Complexe : 2 + 3i

print(z1+z2) # affiche le résultat de l'addition

Le code affiche :

3 + 5i

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

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

 
Sélectionnez
class Complexe:
 
    def __init__(self, part_reel=0, part_imag=0): # méthode constructeur de la classe
        self.reel = part_reel # on définit la partie réelle du nombre complexe
        self.imag = part_imag # on définit la partie imaginaire du nombre complexe
 
    def __str__(self): # permet d'afficher le nombre complexe sous la forme algébrique a + bi
        return "{0} + {1}i".format(self.reel, self.imag) if self.imag>=0 else "{0} - {1}i".format(self.reel, abs(self.imag))
 
    def __add__(self, other): # méthode permettant de redéfinir l'opérateur « + » pour 2 nombres complexes : z1 + z2 = (a + bi) + (c + di) = (a+c) + (b+d)i 
        part_reel = self.reel + other.reel # on évalue la partie réelle du nombre complexe résultat de l'addition
        part_imag = self.imag + other.imag # on évalue la partie imaginaire du nombre complexe résultat de l'addition
        return Complexe(part_reel, part_imag) # renvoie le nombre complexe résultat de l'addition
 
    def __mul__(self, other): # méthode permettant de redéfinir l'opérateur « * » pour 2 nombres complexes : z1 * z2 = (ac - bd) + (ad + bc)*i 
        part_reel = self.reel * other.reel - self.imag * other.imag # part_reel = (ac - bd)
        part_imag = self.reel * other.imag + self.imag * other.reel # part_imag = (ad + bc)
        return Complexe(part_reel, part_imag) # renvoie le nombre complexe résultat de la multiplication

Cette méthode offre donc la possibilité de redéfinir l'opération de multiplication pour 2 nombres complexes en utilisant l'égalité :

(a + bi) x (c + di) = (ac - bd) + (ad + bc)i

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

 
Sélectionnez
z1 = Complexe(1, 2) # création du 1er objet de la classe Complexe : 1 + 2i
z2 = Complexe(2, 3) # création du 2e objet de la classe Complexe : 2 + 3i

print(z1*z2) # affiche le résultat du produit

Le code affiche :

-4 + 7i

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 Complexe, nous pouvons ajouter une méthode __pow__() qui va permettre d'évaluer un nombre complexe z élevé à la puissance n.

 
Sélectionnez
class Complexe:
 
    def __init__(self, part_reel=0, part_imag=0): # méthode constructeur de la classe
        self.reel = part_reel # on définit la partie réelle du nombre complexe
        self.imag = part_imag # on définit la partie imaginaire du nombre complexe
 
    def __str__(self): # permet d'afficher le nombre complexe sous la forme algébrique a + bi
        return "{0} + {1}i".format(self.reel, self.imag) if self.imag>=0 else "{0} - {1}i".format(self.reel, abs(self.imag))
 
    def __add__(self, other): # méthode permettant de redéfinir l'opérateur « + » pour 2 nombres complexes : z1 + z2 = (a + bi) + (c + di) = (a+c) + (b+d)i 
        part_reel = self.reel + other.reel # on évalue la partie réelle du nombre complexe résultat de l'addition
        part_imag = self.imag + other.imag # on évalue la partie imaginaire du nombre complexe résultat de l'addition
        return Complexe(part_reel, part_imag) # renvoie le nombre complexe résultat de l'addition
 
    def __mul__(self, other): # méthode permettant de redéfinir l'opérateur « * » pour 2 nombres complexes : z1 * z2 = (ac - bd) + (ad + bc)*i 
        part_reel = self.reel * other.reel - self.imag * other.imag # part_reel = (ac - bd)
        part_imag = self.reel * other.imag + self.imag * other.reel # part_imag = (ad + bc)
        return Complexe(part_reel, part_imag) # renvoie le nombre complexe résultat de la multiplication
 
    def __pow__(self, n): # méthode permettant de redéfinir l'opérateur de puissance : self ** n
        z = Complexe(1,0) # on initialise la variable objet z avec la valeur 1 élément neutre pour la multiplication de nombres complexes
        for i in range(n): # nous multiplions n fois z par self à l'aide de l'opérateur *
            z = z*self # équivalent à : z = z.__mul__(self)
        return z # renvoie le nombre complexe résultat de l'opération (self ** n)

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

 
Sélectionnez
z = Complexe(1, 1)
print(z**3)

Le code renvoie :

-2 + 2i


Vérification

z3 = (1 + i)3

z3 = (1 + i) × (1 + i) × (1 + i)

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

z3 = (0 + 2i) × (1 + i)

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

z3 =-2 + 2i


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

Opérateur

Expression

Interprétation Python

Addition

z1 + z2

z1.__add__(z2)

Soustraction

z1 - z2

z1.__sub__(z2)

Multiplication

z1 * z2

z1.__mul__(z2)

Puissance

z1 ** z2

z1.__pow__(z2)

Division

z1 / z2

z1.__truediv__(z2)

Division entière

z1 // z2

z1.__floordiv__(z2)

Modulo

z1 % z2

z1.__mod__(z2)

...

...

...

III-D. Surcharge de l'opérateur de comparaison « == »

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

 
Sélectionnez
class Complexe:
 
    def __init__(self, part_reel=0, part_imag=0): # méthode constructeur de la classe
        self.reel = part_reel # on définit la partie réelle du nombre complexe
        self.imag = part_imag # on définit la partie imaginaire du nombre complexe
 
    #------------------------------------------------------
    
   def __eq__(self, other): # méthode permettant de redéfinir l'opérateur « == » pour 2 nombres complexes 
        return (self.reel==other.reel) and (self.imag==other.imag) # renvoie True si les parties réelles et imaginaires des 2 nombres complexes sont égales

Cette méthode permet donc de redéfinir l'opérateur de comparaison « == » pour deux nombres complexes en testant si leurs parties réelles et imaginaires sont égales :

 
Sélectionnez
z1 = Complexe(1, 2) # création du 1er objet de la classe Complexe : 1 + 2i
z2 = Complexe(1, 2) # création de 2e objet Complexe : 1 + 2i

print(z1==z2) # 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 à

z1 < z2

z1.__lt__(z2)

Inférieur ou égal à

z1 <= z2

z1.__le__(z2)

Egal

z1 == z2

z1.__eq__(z2)

...

...

...

Si vous souhaitez avoir une liste plus complète des opérateurs, je vous invite à consulter cette pagepage.

À noter qu'il existe également un module cmathcmath pour Python contenant des fonctions mathématiques pour les nombres complexes.

IV. Conclusion

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

Chacun pourra ensuite librement ajouter d'autres opérateurs à la classe Complexe ou bien en créer une autre, basée par exemple sur la représentation trigonométrique des nombres complexes.

V. Module Python

Il contient le code complet de la classe Complexe :

Classe Complexe
Cacher/Afficher le codeSélectionnez

VI. Remerciements

Je tiens à remercier Malick pour le suivi de cet article, ainsi que escartefigue pour sa relecture.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

Copyright © 2022 Denis Hulo. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts. Droits de diffusion permanents accordés à Developpez LLC.