La méthode de Jacobi (python)

Bonsoir tout le monde. J'ai un problème concernent la méthode de Jacobi de la résolution des système linéaires sous Python.
Mon code avec un exemple d'application, est :
from math import *
from numpy import *
from scipy import *
from scipy import linalg 

def Jacobi(A,b,eps,x_0):
    D=diag(diag(A))
    N=D-A
    x=x_0
    i=0
    Eps=2*eps
    while eps<Eps :
        x=dot(linalg.inv(D),dot(N,x))+dot(linalg.inv(D),b)
        Eps=linalg.norm(dot(A,x)-b)
        i=i+1
    return x
    
A=np.array([[1,1,1],[1,2,2],[1,2,3]]) 
b=array([2,2,8])
Et l'erreur est :
ValueError: array must not contain infs or NaNs
Je ne comprends pas ce type d'erreur et je ne sais pas quoi faire, merci de me donner des idées pour remédier le problème.

Réponses

  • Plusieurs remarques :

    * from math import * est plutôt à éviter, il vaut mieux utiliser les fonctions mathématiques de numpy et sympy
    * from scipy import linalg est inutile puisque tu as déjà fait from scipy import *
    * il vaut éviter de faire plusieurs import * car ça peut créer des conflits, surtout que tu ne te sers pas de math et de scipy
    * ton i ne sert à rien
    * il vaut mieux calculer une fois pour toute l'inverse de D au lieu de le refaire à chaque fois

    Sinon ça ne marche pas car la méthode de Jacobi n'est valable que pour les matrices à diagonale dominante, ce qui n'est pas le cas pour ta matrice $A$. Si on essaye une matrice qui convient, ça marche :
    from numpy import *
    
    def Jacobi(A,b,eps,x_0):
        D = diag(diag(A))
        N = D - A
        x = x_0
        invD = linalg.inv(D)
        while linalg.norm(dot(A,x)-b) > eps:
            x = dot(invD,dot(N,x)) + dot(invD,b)
        return x
        
    A = array([[3,1,1],[1,-3,2],[-1,2,4]]) 
    b = array([2,2,8])
    
    print(Jacobi(A,b,0.001,array([0,0,0])))
    print(linalg.solve(A,b))
    
  • Bonjour,
    invD = diag(1.0/diag(A))
    
    évite un calcul de matrice inverse.
    D'autre part, il vaut mieux faire le produit
    dot(invD,b)
    
    une seule fois en dehors de la boucle.

    Cordialement,

    Rescassol
  • Pour répondre à la question sur le type d'erreur, si on fait afficher les résultats intermédiaires sur ton premier exemple, on voit que les valeurs de $x$ explosent !
    On aboutit assez rapidement à dépasser le plus grand flottant représentable sur 64 bits, et le résultat est remplacé dans le tableau Numpy par "inf" ou par "NaN" (pour "Not a Number") suivant le calcul effectué.
    Au calcul suivant, Numpy râle car il ne sait pas poursuivre le calcul... ce qui est assez logique.
  • Rescassol, tu as parfaitement raison !
  • Merci a vous tous
Connectez-vous ou Inscrivez-vous pour répondre.