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
| #!/usr/bin/env python3
# coding: utf-8
class cPoly:
# Getters/Setters
coeff=property(lambda self: self.__coeff)
degre=property(lambda self: len(self.__coeff) - 1)
# Simplification des zéros non significatifs
@staticmethod
def __simplify(coeff):
if len(coeff) == 1: return coeff
i=0
while coeff[i] == 0: i+=1
return coeff[i:]
# __simplify()
# Complétion de zéros
@staticmethod
def completeZ(p, n):
if len(p.coeff) > n: return p.coeff
return (0,) * (n - len(p.coeff)) + p.coeff
# completeZ()
# Création de l'objet
def __init__(self, *args):
if len(args) == 0:
self.__coeff=()
return
# if
self.__coeff=tuple(cPoly.__simplify(args))
# __init__()
# Longueur de l'objet (c'est la longueur de ses coeff)
def __len__(self):
return len(self.coeff)
# Pour afficher l'objet
def __str__(self):
return "[%s]" % ", ".join(map(str, self.coeff))
# Opposé du polynome
def __neg__(self):
return cPoly(*(-x for x in self.coeff))
# Opposé de l'opposé (l'identité quoi)
def __pos__(self):
return self
# Egalité de deux polynomes
def __eq__(self, other):
# Si autre chose n'est pas un polynome
if not isinstance(other, cPoly):
# On le convertit en polynome
other=cPoly(other)
# Les polynomes sont égaux si leurs coefficients le sont
return self.coeff == other.coeff
# __eq__()
# Différence de deux polynomes
def __ne__(self, other):
return not self == other
# Relation d'ordre inférieur à
def __lt__(self, other):
# Si autre chose n'est pas un polynome
if not isinstance(other, cPoly):
# On le convertit en polynome
other=cPoly(other)
# Evaluation des degrés
if self.degre != other.degre: return self.degre < other.degre
# Evaluation des coeff
return self.coeff < other.coeff
# __lt__()
# Relation d'ordre supérieur à
def __gt__(self, other):
# Si autre chose n'est pas un polynome
if not isinstance(other, cPoly):
# On le convertit en polynome
other=cPoly(other)
# Evaluation des degrés
if self.degre != other.degre: return self.degre > other.degre
# Evaluation des coeff
return self.coeff > other.coeff
# __gt__()
# Relation d'ordre inférieur ou égal
def __le__(self, other):
return self < other or self == other
# Relation d'ordre supérieur ou égal
def __ge__(self, other):
return self > other or self == other
# Addition du polynome avec autre chose
def __add__(self, other):
# Si autre chose n'est pas un polynome
if not isinstance(other, cPoly):
# On le convertit en polynome
other=cPoly(other)
m=max(len(self), len(other))
return cPoly(
*(
(x + y) for (x, y) in zip(
cPoly.completeZ(self, m),
cPoly.completeZ(other, m),
)
)
)
# __add__()
# Addition renversée (si on demande n+poly)
def __radd__(self, other):
# On renvoie poly+n
return self+other
# Soustraction du polynome avec autre chose
def __sub__(self, other):
return self + (-other)
# Soustraction renversée (si on demande n-poly)
def __rsub__(self, other):
# On renvoie poly-n
return self-other
# Multiplication du polynome par autre chose
def __mul__(self, other):
# Si autre chose n'est pas un polynome
if not isinstance(other, cPoly):
# On le convertit en polynome
other=cPoly(other)
# Si un polynome est vide
if not all(map(len, (self, other))): return cPoly()
res=[0,] * (len(self) + len(other) - 1)
for (i1, c1) in enumerate(self.coeff):
for (i2, c2) in enumerate(other.coeff):
res[i1+i2]+=c1*c2
# for
return cPoly(*res)
# __mul__()
# Multiplication renversée (si on demande n*poly)
def __rmul__(self, other):
# On renvoie poly*n
return self*other
# Puissance
def __pow__(self, n):
p=cPoly(1)
for i in range(n): p*=self
return p
# __pow__()
# Evaluation en un point x
def eval(self, x):
return sum(c*x**i for (i, c) in enumerate(reversed(self.coeff)))
# Dérivée
def derivee(self):
return cPoly(
*reversed(
[c*i for (i, c) in enumerate(reversed(self.coeff[:-1]), 1)]
)
)
# derivee()
# Résolution f(x) == n par méthode de Newton
# Ce calcul pourra prendre en charge plusieurs x0 pour donner plusieurs résultats
def newton(self, n=0, tabX=(0, ), iter_max=100, precision=1e-9):
polyCalc=self - n # Calculer f(x) == n c'est calculer f(x)-n == 0
polyD=polyCalc.derivee()
for (i, x) in enumerate(tabX):
for _ in range(iter_max):
polyX=polyCalc.eval(x)
if abs(polyX) < precision:
yield (tabX[i], x)
break
# if
deriveX=polyD.eval(x)
#if deriveX == 0:
#yield (tabX[i], None)
#break
# if
x-=polyX/deriveX if deriveX != 0 else polyX
else:
# Pas de solution pour ce x0
yield (tabX[i], None)
# for
# for
# newton()
# cPoly()
# Allez, on s'éclate maintenant...
a=cPoly(1, -7, 12)
print("poly=%s, derivee=%s, inf: %s, sup: %s" % (a, a.derivee(), a < a.derivee(), a > a.derivee()))
b=cPoly(7, 8, 9)
print("poly=%s, derivee=%s, inf: %s, sup: %s" % (b, b.derivee(), b < b.derivee(), b > b.derivee()))
print("a > b: ", a > b)
print("a < b: ", a < b)
print("a carré: ", a*a, a**2)
print("b carré: ", b*b, b**2)
print("somme=%s, derivee=%s" % (a+b, (a+b).derivee()))
print("produit=%s, derivee=%s" % (a*b, (a*b).derivee()))
c=(a+b)*(a-b)
assert c == a**2 - b**2
print("poly=%s, derivée1=%s, dérivée2=%s" % (c, c.derivee(), c.derivee().derivee()))
c=cPoly(1, 0, -2)
n=0.5
print("Résolution %s = %s: %s" % (c, n, tuple(c.newton(n=n, tabX=(0, 1, 2, 3))))) |