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 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
| def regrouper_termes(liste_termes):
# permet de regrouper les termes identiques dans une liste triée en utilisant les règles R4 et R5 :
# R5 : a*a + b + a*a + b + c = a*a + a*a + b + b + c (tri)
# R4 : a*a + a*a + b + b + c = 2*a*a + 2*b + c (regroupement)
# [(1,('a', 'a')), (1,('b',)), (1,('a', 'a')), (1,('b',)), (1,('c',))] -> [(2,('a','a')), (2,('b',)), (1,('c',))]
# créer une liste triée de variables ou de tuples uniques : [(1,('a', 'a')), (1,('b',)), (1,('a', 'a')), (1,('b',)), (1,('c',)] -> [('a','a'), ('b',), ('c',)]
liste_vars = [t[1] for t in liste_termes]
liste_vars_uniques = sorted(set(liste_vars)) # règle R5
# initialisation de la liste de termes à renvoyer
liste_termes_groupes = []
# parcours les variables uniques de la liste
for var in liste_vars_uniques:
# compte le nombre de fois que la variable est présente dans la liste
coef = sum([t[0] for t in liste_termes if t[1]==var]) # Règle R4
if coef!=0: # si le coef. n'est pas égal à 0
# ajout du tuple (coef,var) à la liste : liste_termes_groupes.append((2,('a',)))
liste_termes_groupes.append((coef,var))
# renvoie de la liste des termes groupés
return liste_termes_groupes
class Polynome:
def __init__(self, termes): # méthode constructeur de la classe
# on s'assure que l'argument termes est une liste
if not isinstance(termes, list): termes = [termes]
# parcours des indices et des termes de la liste
for indice, terme in enumerate(termes):
# si le terme est de type string : 'a'
if isinstance(terme, str):
# on met à jout l'élément de la liste avec un tuple de la forme (1,('a',)) : (coef, var)
termes[indice] = (1,(terme,))
elif len(terme)<=1 or not isinstance(terme[0], (int, float)): # ou si le terme est un tuple à un seul élément : ('a',)
termes[indice] = (1,terme)
# regroupement des termes identiques en utilisant les règles R4 et R5
termes = regrouper_termes(termes)
# on définit la liste de termes correspondant au polynôme. Ex. : [(1,('a','a')), (2,('a','b')), (1,('b','b'))] -> a^2 + 2ab + b^2
self.liste_termes = termes
def __str__(self): # permet d'afficher l'expression sous sa forme développée et réduite
# initialise la chaîne à renvoyer
chaine_expression = ''
# si le polynôme est égal à un nombre : p=1
if (len(self.liste_termes)==1) and self.liste_termes[0][1]==():
return str(self.liste_termes[0][0]) # renvoie le nombre
# parcours de la liste de termes du polynôme
for terme in self.liste_termes:
# création de la liste de variables uniques : ['a', 'b', 'c']
liste_vars = sorted(set(terme[1]))
if liste_vars==[]: # si c'est un nombre
chaine_terme=str(terme[0])
else: # sinon
# si le coefficient du terme vaut 1 : (1,'a')
if terme[0]==1:
chaine_terme='' # on part d'une chaîne vide
else: # sinon
chaine_terme=str(terme[0]) + '*' # on part d'une chaîne contenant le coef. : '2*'
# parcours des variables du terme : ('a','a','b') -> a*a*b = (a^2)*b
for var in liste_vars:
# évalue l'exposant de la variable : ('a','a','a') -> a^3 (R1)
exp = len([v for v in terme[1] if v==var])
# si l'exposant vaut 1
if exp==1:
chaine_terme += var + '*'
else: # sinon
chaine_terme += var + '^' + str(exp) + '*'
chaine_terme = chaine_terme[:-1]
chaine_expression += chaine_terme + " + "
# renvoie la chaîne représentant l'expression du polynôme
return chaine_expression[:-3].replace(" + -1*"," - ").replace("-1*","-")
def __add__(self, other): # méthode permettant de redéfinir l'opérateur « + » pour 2 objets Polynome : self + other
# concaténation des 2 listes de termes
# [(1,('a', 'a')), (1,('b',))] + [(1,('a', 'a')), (1,('b',))] = [(1,('a', 'a')), (1,('b',)), (1,('a', 'a')), (1,('b',))]
# tri et regroupement des termes identiques en utilisant les règles R4 et R5 :
# R5 : a*a + b + a*a + b -> a*a + a*a + b + b (tri)
# R4 : a*a + a*a + b + b -> 2*a*a + 2*b (regroupement)
# [(1,('a', 'a')), (1,('b',)), (1,('a', 'a')), (1,('b',))] -> [(2,('a','a')), (2,('b',))]
# concaténation des 2 listes de termes de self et other
liste_termes = self.liste_termes + other.liste_termes
# renvoie l'objet Polynome résultat de l'addition de self et other avec regroupement des termes identiques
return Polynome(liste_termes)
def __sub__(self, other): # méthode permettant de redéfinir l'opérateur « - » pour 2 objets Polynome : self - other
# concaténation des 2 listes de termes
# [(1,('a',)), (1,('b',))] + [(1,('a','a')), (1,('b',))] = [(1,('a',)), (1,('b',)), (1,('a','a')), (1,('b',))]
# tri et regroupement des termes identiques en utilisant les règles R4 et R5 :
# R5 : a + b - a*a - b -> a - a*a + b - b (tri)
# R4 : a - a*a + b - b -> a - a*a (regroupement)
# [(1,('a',)), (1,('b',)), (-1,('a','a')), (-1,('b',))] -> [(1,('a',)), (-1,('a','a'))]
# met un signe - devant les coefficients de la liste des termes de other
other_liste_termes=[(-terme[0],terme[1]) for terme in other.liste_termes]
# concaténation des 2 listes de termes de self et other
liste_termes = self.liste_termes + other_liste_termes
# renvoie l'objet Polynome résultat de la soustraction de self et other avec regroupement des termes identiques
return Polynome(liste_termes)
def __mul__(self, other): # méthode permettant de redéfinir l'opérateur « * » pour 2 objets Polynome : self * other
# règles R2, R3, R4 et R5
# R2 : (a+b)*(a+b) = (a+b)*a + (a+b)*b
# R3 : = a*(a+b) + b*(a+b)
# R2 : = a*a + a*b + b*a + b*b
# R3 = a*a + a*b + a*b + b*b
# R4 : = a*a + 2*a*b + b*b
# initialisation de la liste de termes
liste_termes = []
# si le 2e membre est un numérique
if isinstance(other, (int,float)):
# on multiplie les coefficients des termes de self.liste_termes par other
liste_termes = [(other*terme[0],terme[1]) for terme in self.liste_termes]
return Polynome(liste_termes)
# parcours des termes de la liste de other
for terme_droite in other.liste_termes:
# parcours des termes de la liste de self
for terme_gauche in self.liste_termes:
coef = terme_droite[0]*terme_gauche[0]
var = terme_droite[1] + terme_gauche[1]
# tri des variables
var = tuple(sorted(var))
# ajout du tuple (coef,var) à la liste
liste_termes.append((coef,var))
# renvoie l'objet Polynome résultat de la multiplication de self et other avec regroupement des termes identiques
return Polynome(liste_termes)
def __pow__(self, n): # méthode permettant de redéfinir l'opérateur de puissance : self ** n
# on utilise pour cela la règles R1 :
# R1 : ∀x, x^2 = x∗x
# a^2 = a*a
# a^3 = a*a*a
#...
# on initialise la variable objet p avec un polynôme égal à 1
p = Polynome((1,()))
# on multiplie n fois p par self à l'aide de l'opérateur *
for i in range(n):
p = p*self # équivalent à : p = p.__mul__(self)
# renvoie l'objet Polynome résultat de l'opération (self ** n)
return p
def __eq__(self, other): # méthode permettant de redéfinir l'opérateur « == » pour 2 polynômes
# renvoie True si les listes de termes des 2 polynômes sont égales
return (self.liste_termes==other.liste_termes)
def coefficients_polynome(poly):
# initialisation de la liste des coefficients
liste_coefficients = []
liste_termes=[]
# parcours des termes du polynôme passé en argument
for terme in poly.liste_termes:
# création de la liste de variables sans le 'X' : ('x1','x2')
liste_vars = tuple([t for t in terme[1] if t!='X'])
# ajout du tuple (coef,vars) à la liste
liste_termes.append((terme[0],liste_vars))
# détermination du nombre de coefficients du polynôme : ('a3','x1','x2','x3') -> 4
nombre_coefficients = max([len(t[1]) for t in liste_termes])
# parcours des indices des coefficients : 0 -> nombre_coefficients-1
for indice_coefficient in range(nombre_coefficients):
# création de la liste des termes du polynôme associés aux coefficients, avec comme formule des coefs : a(n-k) = (-1)^k*an*σk(x1,...,xn)
termes_polynome =[terme for terme in liste_termes if len(terme[1])==(nombre_coefficients-indice_coefficient)]
# ajout du polynôme à la liste
liste_coefficients.append(Polynome(termes_polynome))
# renvoie la liste des polynômes associés aux coefficients
return liste_coefficients
# recherche des coefficients du polynôme :
# P = a3X^3 + a2x^2 + a1X + a0
# Il possède 3 racines x1, x2, x3, on peut donc l'écrire sous sa forme factorisée :
# P = a3*(X-x1)*(X-x2)*(X-x3)
# création des objets représentant le coefficient a3, l'indéterminé X et les racines du polynôme
𝑎3 = Polynome('a3') # création d'un 1er objet Polynome représentant le coefficient a3
X = Polynome('X') # création d'un 2e objet représentant la variable X
x1 = Polynome('x1') # création d'un 3e objet représentant la racine x1
x2 = Polynome('x2') # création d'un 4e objet représentant la racine x2
x3 = Polynome('x3') # création d'un 5e objet représentant la racine x3
# création d'un objet Polynome à partir de l'expression a3*(X-x1)*(X-x2)*(X-x3)
P = a3*(X-x1)*(X-x2)*(X-x3)
# détermination des coefficients du polynôme en fonction de ses racines
coefs_polynome = coefficients_polynome(P)
# nombre de racines
n=3
print("Coefficients du polynôme exprimés en fonction de ses racines :")
# parcours des coefficients du polynôme de an à a0, avec comme formule des coef. : a(n-k) = (-1)^k*an*σk(x1,...,xn)
for k,p in enumerate(reversed(coefs_polynome)):
if k>0: # on choisit de ne pas afficher an = an
# affiche a(n-k) = ...
print('a{0} = '.format(n-k) + p.__str__()) |