-
Polygnome a été codé par Ulysse Lojkine en 2010 pour le projet ALEV (Algorithmie et Logique dans les Espaces Virtuels) du lycée Henri IV.
-
Polygnome est placé sous licence libre GNU-GPL par son programmeur.
-
Quelques infos d'utilisation... 3.1. Pour entrer un nouveau polynôme... 3.1.1. Séparez les monômes par le signe +. 3.1.2. Utilisez le signe - et le signe + pour entrer des coefficients négatifs. 3.1.3. Séparez le numérateur et le dénominateur par le signe / si vous voulez utiliser des coefficients rationnels. 3.1.4. N'utilisez pas d'espace. 3.1.5. Exemple : "7x8+x5+5/3x+-8" 3.2. Pour entrer une formule... 3.2.1. Pour nommer un polynôme, utilisez la lettre f suivie de son numéro dans la liste. 3.2.2. Utilisez les opérateurs arithmétiques usuels... 3.2.2.1. Le + pour l'addition. 3.2.2.2. Le - pour la soustraction. 3.2.2.3. Le * pour la multiplication. 3.2.2.4. Le ** pour la puissance. 3.2.2.5. Le / pour la division (factorisation). 3.2.2.6. Les parenthèses () pour isoler une expression. 3.2.3. À l'exception de l'opérateur & utilisé à la place du rond pour la composition. 3.2.4. Exemple : "(f0+f2)**7 - f1"
-
Si vous cherchez un programme complet, ne négligez pas Polynomial. 4.1. Polynomial est disponible... 4.1.1. fichiers par RubyGem 4.1.2. source en ligne à https://github.com/adrianomitre/Polynomial/tree/gh-pages 4.2. Fonctionnalités supplémentaires... 4.2.1. Coefficients complexes. 4.2.2. Meilleure gestion des erreurs. 4.2.3. Peut-être d'autres choses. 4.3. Inconvénients... 4.3.1. Ce n'est pas moi qui l'ai fait. 4.3.2. Tous les coefficients même nuls sont enregistrés. 4.3.3. Source en anglais.
Created
February 3, 2012 22:01
-
-
Save lovasoa/1732967 to your computer and use it in GitHub Desktop.
polygnome
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Classe principale | |
# Retourne 0 si nil, nombre sinon | |
def obj2nbr(obj) | |
return (obj == nil) ? 0 : obj | |
end | |
class Polynome | |
require 'rational' | |
require 'complex' | |
# Toutes les variables de classe sont lisibles depuis l'extérieur | |
attr_reader :str, :liste, :derivee, :deg | |
# Fonction d'initialisation (appelée par Polynome.new(str)) | |
def initialize(poly=0) #Par défaut, on crée le polynôme nul | |
if poly.is_a? Hash : @liste = poly # expression du polynôme sous forme de liste ; ex. : {0 => 1, 1 => 1, 3 => 4} | |
elsif poly.is_a? Numeric : @liste = {0 => poly} | |
elsif poly.is_a? String : @liste = fromString(poly).liste | |
else raise "L'argument doit être un hash, une constante, ou une chaîne de caractères. Vous avez fourni '"+poly.inspect+ "'." | |
end | |
@liste.default = 0 #Tous les monômes qui n'ont pas été définis ont un coefficient nul | |
@liste.delete_if {|k, v| v==0} # on supprime tous les monômes nuls | |
@deg = liste.empty? ? -(1.0/0) : @liste.keys.max # degré du polynôme ; ex. : 4. Le degré du polynôme nul est moins l'infini | |
end | |
# Passage de la chaîne à la liste, en moins bien, par Ophir | |
def fromString(str) | |
str = str.downcase.tr(" ","") | |
polyFinal = Polynome.new({0=>0}) # Le polynôme nul | |
polyActuel = Polynome.new({0=>1}) # 1 | |
i=0 | |
while i < str.length | |
case str [i..i] | |
when "(" : | |
newPos = str[i+1..-1].index(")") + i+1; | |
polyParentheses = fromString(str[ i+1 .. newPos-1]) | |
i=newPos+1 #newPos + 1: le caractère après la parenthèse fermante | |
if str[i .. i] == "^": | |
newPos = str[i+1 .. -1].index(/[^0-9]|$/)+i+1; | |
polyActuel *= polyParentheses ** (str[i+1 .. newPos-1].to_i) | |
i=newPos | |
else | |
polyActuel *= polyParentheses | |
end | |
when "+": | |
polyFinal += polyActuel | |
polyActuel = Polynome.new(1) # P(X) = 1 | |
i+=1 | |
when "-": | |
polyFinal += polyActuel | |
polyActuel = Polynome.new(-1) # P(X) = -1 | |
i+=1 | |
when "x": | |
if str[i+1 .. i+1] == "^": | |
newPos = str[i+2 .. -1].index(/[^0-9]|$/)+i+2; | |
puissance = str[i+2 .. newPos-1].to_i #i+1 parce que le caractère ^ est en position i+1 | |
i=newPos | |
else | |
puissance = 1 | |
i=i+1 | |
end | |
polyActuel *= Polynome.new({puissance => 1})# P(X) = X^puissance | |
when "0".."9", "i": | |
newPos = str[i..-1].index(/[^0-9]|$/)+i; | |
coeff = (i==newPos) ? 1 : str[i .. newPos-1].to_f | |
coeff = Integer(coeff) if coeff == Integer(coeff) | |
if str[newPos .. newPos] == "i" #Complexe | |
coeff = Complex(0,coeff) | |
newPos+=1 | |
end | |
polyActuel *= coeff #Polynôme constant égal à coeff | |
i=newPos | |
else #Valeur non reconnue | |
i+=1 | |
end | |
end | |
return (polyActuel+polyFinal) | |
end | |
# Dérivation du polynôme | |
def deriver(ordre=1) | |
if ordre == 1 | |
retour = {} # on crée un hash vide (retour une fois rempli) | |
# La dérivée d'un monôme de degré non nul est de degré deg-1 et de coefficient coeff*deg | |
@liste.each {|deg, coeff| retour [deg -1] = coeff*deg if deg > 0} | |
return Polynome.new(retour) | |
else | |
return self.deriver(ordre-1).deriver() | |
end | |
end | |
# Intégration du polynôme | |
def integrer(ordre=1) | |
if ordre == 1 | |
retour = {} # on crée un hash vide (retour une fois rempli) | |
# La dérivée d'un monôme de degré non nul est de degré deg-1 et de coefficient coeff*deg | |
@liste.each {|deg, coeff| retour[deg +1] = Rational(coeff,deg+1)} | |
return Polynome.new(retour) | |
else | |
return self.integrer(ordre-1).integrer() | |
end | |
end | |
def racines | |
a,b,c = liste[2], liste[1], liste[0] | |
if deg==2 | |
delta = b**2 - 4*a*c | |
return [(-b-Math.sqrt(delta))/(2*a)] if delta==0 | |
return [(-b-Math.sqrt(delta))/(2*a), (-b+Math.sqrt(delta))/(2*a)] | |
elsif deg==1 | |
return [Rational(c,-b)] | |
else | |
raise "Impossible de trouver les racines." | |
end | |
end | |
# Somme de polynômes | |
def +(poly2) | |
return self+Polynome.new(poly2) if poly2.is_a? Numeric | |
retour = poly2.liste.clone | |
@liste.each { |k, v| retour[k] += v} #On additonne tous les monomes de @liste 1 par 1 | |
return Polynome.new(retour) | |
end | |
def -@ | |
self*(-1) | |
end | |
# Différence de polynômes | |
def -(poly2) | |
return self + (-poly2) # a + b = a + (-1)b | |
end | |
# Produit de polynômes | |
def *(poly2) | |
return self*Polynome.new(poly2) if !poly2.is_a? Polynome | |
retour = {} | |
retour.default=0 | |
self.liste.each{ |k1, v1| poly2.liste.each{ |k2, v2| | |
retour[k2+k1] += v1*v2 | |
}} | |
return Polynome.new(retour) # on retourne le polynôme créé à partir du hash | |
end | |
# Puissance d'un polynôme | |
def **(n) | |
if n<0 | |
raise "Impossible d'avoir une puissance négative." | |
end | |
# f^n = f*f^(n-1) = ... = f*f*f*...*f | |
return (n == 0) ? Polynome.new(1) : self * self ** (n - 1) | |
end | |
alias ^ ** | |
def division (dividende, diviseur) #Factorisation | |
return [self*Rational(1,diviseur), 0] if diviseur.is_a? Numeric | |
raise "Division par zéro !" if diviseur.liste.empty? # On ne peut pas diviser par le polynôme nul | |
# Le dividende est le polynôme depuis lequel la fonction est appelée | |
# Le diviseur est l'argument | |
# Le résultat est au départ le polynôme nul | |
quotient, reste = Polynome.new(0), dividende.clone | |
# Jusqu'à ce qu'il n'y ait plus rien à diviser, on applique l'algorithme de division polynômiale | |
while reste.deg >= diviseur.deg | |
monome = Polynome.new({ | |
(reste.deg-diviseur.deg) => #Degré du monôme | |
Rational(reste.liste[reste.deg], diviseur.liste[diviseur.deg]) }) #Coefficient du monôme | |
quotient += monome | |
reste -= monome * diviseur | |
end | |
return [quotient, reste] | |
end | |
def /(diviseur) | |
return division(self, diviseur)[0] | |
end | |
def %(diviseur) | |
return division(self, diviseur)[1] | |
end | |
# Composition | |
def & (poly2) | |
retour = Polynome.new(0) | |
@liste.each {|deg, coeff| retour += coeff * poly2 ** deg} | |
return retour | |
end | |
# Affichage | |
def to_s | |
return "0" if is_null? | |
retour = "" # on crée une chaîne vide qui, une fois remplie, sera retournée | |
# Pour chaque monôme on ajoute à la chaîne le coeff, la variable, le deg, le symbole + | |
@liste.keys.sort.reverse.each {|deg| | |
retour += ((@liste[deg] < 0) ? " - " : " + ") if deg != @deg or @liste[deg] == -@liste[deg].real.abs | |
if (@liste[deg]!=1 && @liste[deg]!=-1) || deg == 0 | |
if @liste[deg].real == @liste[deg] #Si le coefficient est réel | |
retour += @liste[deg].abs.to_s | |
else #Si le coefficient est complexe | |
retour += format("(%s)", @liste[deg].to_s) | |
end | |
end | |
if deg != 0 | |
retour += "X" | |
if deg != 1 | |
retour += "^"+deg.to_s | |
end | |
end | |
} | |
return retour.strip | |
end | |
alias inspect to_s | |
def coerce(x)#Permet de rendre les opérations commutatives, donc d'avoir 3*Poly | |
[self, x] | |
end | |
def is_null? | |
@liste=={} | |
end | |
end | |
X = Polynome.new({1=>1}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment