équations second degré python ia

Équations du second degré en Python avec IA

  • Dernière modification de la publication :20 juin 2023
  • Temps de lecture :9 min de lecture
  • Commentaires de la publication :2 commentaires

Loading

Les équations du second degré, ou équations quadratiques, sont très faciles à résoudre mathématiquement, mais dès lors que l’on souhaite écrire un programme en Python permettant de les résoudre, c’est autre chose…

J’ai voulu testé deux manières de concevoir un programme de résolution des équations quadratiques à l’aide de l’intelligence artificielle après avoir moi-même écrit un programme, histoire de comparer…

Alors oui, je sais, j’ai déjà écrit un article sur ce thème, mais je faisais appel à Xcas. Je voudrais maintenant être le plus autonome possible et donc ne me contenter que d’une solution Python pure.

Conception d’un programme avec ChatGPT

Le prompt que j’ai saisi sur chatGPT est le suivant:

Peux-tu me donner un programme écrit en Python qui permet de résoudre une équation du second degré sur l'ensemble des nombres réels ?

Et voici sa réponse:

import math

def solve_quadratic(a, b, c):
    discriminant = b**2 - 4*a*c
    
    if discriminant > 0:
        root1 = (-b + math.sqrt(discriminant)) / (2*a)
        root2 = (-b - math.sqrt(discriminant)) / (2*a)
        return root1, root2
    elif discriminant == 0:
        root = -b / (2*a)
        return root
    else:
        return None

# Exemple d'utilisation
a = float(input("Entrez le coefficient a : "))
b = float(input("Entrez le coefficient b : "))
c = float(input("Entrez le coefficient c : "))

solutions = solve_quadratic(a, b, c)

if solutions is None:
    print("Pas de solution réelle.")
elif isinstance(solutions, tuple):
    print("Les solutions sont :", solutions[0], "et", solutions[1])
else:
    print("La solution est :", solutions)

Ce code ne me convient pas car il ne donne que les valeurs approchées des solutions quand le discriminant n’est pas un carré parfait.

Au fait, pour plus de détail sur la résolution mathématique de telles équations, regardez cette page.

Génération d’un programme en Python sous Cursor

C’est grâce à Korben que j’ai eu l’info: cursor est un logiciel qui permet de coder à l’aide de l’IA. J’ai donc voulu voir ce que cela donne. Le résultat en vidéo:

Le programme est le suivant:

import cmath

def solve_quadratic(a, b, c):
    # Calculate the discriminant
    discriminant = cmath.sqrt(b**2 - 4*a*c)

    # Find two solutions
    sol1 = (-b - discriminant) / (2 * a)
    sol2 = (-b + discriminant) / (2 * a)

    return (sol1, sol2)

if __name__ == "__main__":
    a = float(input("Enter the coefficient of x^2 (a): "))
    b = float(input("Enter the coefficient of x (b): "))
    c = float(input("Enter the constant term (c): "))

    solutions = solve_quadratic(a, b, c)

    print("The solutions are {0} and {1}".format(solutions[0], solutions[1]))

À deux poils de cul près, ça ressemble à celui proposé par chatGPT. En fait, c’est pire car j’avais bien demandé de résoudre sur l’ensemble des réels, mais il m’a fait ça sur l’ensemble des nombres complexes cet abruti! Et en anglais en plus ! Pfiou !

N’empêche que ça e me va pas du tout ! Je n’ai toujours pas de valeurs exactes!

Rien ne vaut le travail fait la main (et au cerveau) !

Mon propre programme

Avant de se lancer dans le script, il faut analyser les situations délicates.

Lorsque le discriminant n’est pas un carré parfait, les solutions (quand elles existent) ne sont pas rationnelles. Et même quand le discriminant est un carré parfait, on peut se retrouver avec une solution rationnelle non décimale (par exemple, \(\frac{1}{3}\) qui va s’écrire 0.3333333333333… Beurk!

Il y a donc deux problématiques:

  • simplifier les racines quand il y a des fractions
  • simplifier la racine carrée du discriminant

Pour simplifier les fractions, on peut utiliser le module fractions.

En revanche, pour simplifier la racine carrée du discriminant, il n’y a pas de module à ma connaissance. Il faut donc bidouiller un script… Et ce n’est pas si difficile que ça: on décompose le discriminant en produit de facteurs premiers, que l’on utilise pour simplifier la racine carrée.

Ça donne un programme assez volumineux (86 lignes de code) mais il faut ce qu’il faut!

from fractions import Fraction

"""
Décomposition en produit de facteurs premiers: retourne un dictionnaire de la forme
{ (p1:exp1), ... }
"""
def decomp(n):
    D = dict() # dictionnaire vide
    
    k = 2
    
    while n > 1:
        exposant = 0
        while n%k == 0:
            exposant = exposant + 1
            n = n/k
        if exposant != 0:
            D[k] = exposant
        k = k+1
        j = 2
        while k%j == 0:
            k = k + 1 
        
    return D

"""
Simplification d'une racine carrée
"""
def simp(x):
    x = Fraction(x)
    numer = decomp(x.numerator)
    denom = decomp(x.denominator)
    coef_num, radicand_num = 1, 1
    for facteur, exposant in numer.items():
        coef_num *= facteur**(exposant//2)
        if exposant%2 == 1:
            radicand_num *= facteur
            
    coef_denom, radicand_denom = 1, 1
    for facteur, exposant in denom.items():
        coef_denom *= facteur**(exposant//2)
        if exposant%2 == 1:
            radicand_denom *= facteur
            
    return Fraction(coef_num,coef_denom), Fraction(radicand_num,radicand_denom)

"""
Trouve les éventuelles racines d'un trinôme de degré 2
"""
def racines(*coefs):
    if len(coefs) != 3:
        return 'Erreur dans la saisie des coefficients.'
    else:
        a, b, c = coefs[0], coefs[1], coefs[2]
        delta = b*b - 4*a*c
        if delta < 0:
            r = f'Δ = {delta} < 0 donc le trinôme d\'admet aucune racine.'
        elif delta == 0:
            r = f'Δ = 0 donc le trinôme admet une racine: {Fraction(-b,2*a)}.'
        else:
            coef, radicand = simp(delta) # sous la forme: coef, radicand
            if radicand == 1:
                x1, x2 = Fraction(-b-int(delta**0.5),2*a), Fraction(-b+int(delta**0.5),2*a)
                r = f'Δ = {delta} > 0 donc le trinôme admet deux racines: x₁ = {x1} et x₂ = {x2}.'
            else:
                c = abs(Fraction(coef,2*a))
                if c.numerator == 1:
                    if c.denominator == 1:
                        r = f'Δ = {delta} > 0 donc le trinôme admet deux racines:\n \
x₁ = {Fraction(-b,2*a)} + √({radicand}) et \
x₂ = {Fraction(-b,2*a)} - √({radicand}).'
                    else:
                        r = f'Δ = {delta} > 0 donc le trinôme admet deux racines:\n \
x₁ = {Fraction(-b,2*a)} + √({radicand})/{c.denominator} et \
x₂ = {Fraction(-b,2*a)} - √({radicand})/{c.denominator}.'
                else:
                    if c.denominator == 1:
                        r = f'Δ = {delta} > 0 donc le trinôme admet deux racines:\n \
x₁ = {Fraction(-b,2*a)} + {c.numerator}√({radicand}) et \
x₂ = {Fraction(-b,2*a)} - {c.numerator}√({radicand}).'
                    else:
                        r = f'Δ = {delta} > 0 donc le trinôme admet deux racines:\n \
x₁ = {Fraction(-b,2*a)} + ({c.numerator}/{c.denominator})√({radicand}) et \
x₂ = {Fraction(-b,2*a)} - ({c.numerator}/{c.denominator})√({radicand}).'
            
        return r

Voici quelques exemples de ce qu’il donne:

Pour trouver les racines réelles de \(\frac{1}{4}x^2+\frac{1}{3}x-\frac{1}{5}\):

>>> print( racines(Fraction(1,4),Fraction(1,3),-Fraction(1,5)) )
Δ = 14/45 > 0 donc le trinôme admet deux racines:
 x₁ = -2/3 + (2/3)√(14/5) et x₂ = -2/3 - (2/3)√(14/5).

Si le polynôme est \(x^2+x-1\), cela donne:

>>> print( racines(1,1,-1) )
Δ = 5 > 0 donc le trinôme admet deux racines:
 x₁ = -1/2 + √(5)/2 et x₂ = -1/2 - √(5)/2.

Avec \(x^2-5x+4\):

>>> print( racines(1,-5,4) )
Δ = 9 > 0 donc le trinôme admet deux racines: x₁ = 1 et x₂ = 4.

Pour le moment, je n’ai pas implémenté de solution avec des coefficients radicaux, mais c’est assez simple au final. Il suffit en effet d’implémenter une classe Sqrt.

Je complèterai cet article quand je l’aurai fait très prochainement.

0 0 votes
Évaluation de l'article
S’abonner
Notification pour
guest
2 Commentaires
Le plus ancien
Le plus récent Le plus populaire
Commentaires en ligne
Afficher tous les commentaires
Philippe Rackette

Avec la requête « écrit un programme python en utilisant simpy qui résout toute équation du second degré. » j’obtient de ChatGTP le programme :

import sympy as sp

def resoudre_equation(a, b, c):
    x = sp.symbols('x')
    equation = a*x**2 + b*x + c
    solutions = sp.solve(equation, x)
    return solutions

que je teste avec :

a = sp.Rational(1, 2)
b = sp.sqrt(2)
c = sp.Rational(1,3)+sp.sqrt(3) + 2*sp.I

solutions = resoudre_equation(a, b, c)
print("Les solutions de l'équation sont :", solutions)

Ce qui donne à l’exécution :

Les solutions de l’équation sont : [-sqrt(2) – sqrt(-18*sqrt(3) + 12 – 36*I)/3, -sqrt(2) + sqrt(-18*sqrt(3) + 12 – 36*I)/3]

Je continue avec : « complète le programme suivant pour qu’il écrive un fichier Latex présentant l’équation et ses solutions : ‘import sympy as sp […]' »

ChatGPT complète avec :

def generer_latex(equation, solutions):
    latex_code = "\\documentclass{article}\n\\begin{document}\n"
    latex_code += "L'équation est : $"
    latex_code += sp.latex(equation) + " = 0$"
    latex_code += "\n\nLes solutions de l'équation sont :\n"
    for solution in solutions:
        latex_code += "$x = " + sp.latex(solution) + "$\n"
    latex_code += "\n\\end{document}"
    return latex_code

def ecrire_latex(nom_fichier, latex_code):
    with open(nom_fichier, "w") as fichier:
        fichier.write(latex_code)

a = sp.Rational(1, 2)
b = sp.sqrt(2)
c = sp.Rational(1,3)+sp.sqrt(3) + 2*sp.I

equation, solutions = resoudre_equation(a, b, c)
latex_code = generer_latex(equation, solutions)
ecrire_latex("equation_et_solutions.tex", latex_code)

Le fichier « equation_et_solutions.tex » créé par le programme :

\documentclass{article}

\begin{document}

L’équation est : $\frac{x^{2}}{2} + \sqrt{2} x + \frac{1}{3} + \sqrt{3} + 2 i = 0$

Les solutions de l’équation sont :

$x = – \sqrt{2} – \frac{\sqrt{- 18 \sqrt{3} + 12 – 36 i}}{3}$

$x = – \sqrt{2} + \frac{\sqrt{- 18 \sqrt{3} + 12 – 36 i}}{3}$

\end{document}

et ci-joint une image du résultat compilé.

ChatGPT est tout de même extrêmement efficace et rapide pour obtenir un résultat satisfaisant.

image_equation.png