Résolution matricielle

Samcher 4 Messages postés jeudi 6 octobre 2016Date d'inscription 7 octobre 2016 Dernière intervention - 6 oct. 2016 à 21:11 - Dernière réponse : ucfoutu 18039 Messages postés lundi 7 décembre 2009Date d'inscriptionModérateurStatut 11 avril 2018 Dernière intervention
- 8 oct. 2016 à 08:10
Bonjour,
J'ai un problème au niveau de mon code VBA pour la résolution matricielle d'un système d'équations A*B=X où B et X sont des vecteurs simples et A une matrice carrée. J'ai opté pour l'algorithme "Pivot de Gauss" pour le calcul d'inverse et j'y fais appel dans une autre macro dans laquelle je déclare la matrice A et puis je calcule le vecteur B par une simple multiplication. A chaque fois que j'exécute ma macro, ça me donne des valeurs différentes de A^-1 et B.
Pourriez vous m'expliquer pourquoi et me proposer des solutions?!
Afficher la suite 

10 réponses

Répondre au sujet
Whismeril 11442 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 26 avril 2018 Dernière intervention - 6 oct. 2016 à 21:48
+1
Utile
Bonsoir

Dans ma boule de cristal, je voie une erreur de signe à la ligne 22 de ton code.

Ha tu voulais une réponse sérieuse?

Alors, il faudra poster ton code, la procédure pour qu'il soit lisible et donc maximiser les chances que quelqu'un s'intéresse à ta question est là
http://codes-sources.commentcamarche.net/faq/10686-le-nouveau-codes-sources-comment-ca-marche#balises-code
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de Whismeril
ucfoutu 18039 Messages postés lundi 7 décembre 2009Date d'inscriptionModérateurStatut 11 avril 2018 Dernière intervention - Modifié par ucfoutu le 7/10/2016 à 00:31
0
Utile
1
Bonjour,
Et ajouter à ce que demande Whismeril, que je salue :
montrer où et comment a été déclarée la matrice A

EDIT : ah oui . Et précise le nombre de lignes de colonnes de ta matrice A, ainsi que ce que tu as utilisé pour l'inverser (une formule ? worksheetfunction.Minverse ? Autre ?)

________________________
Nul ne saurait valablement coder ce qu'il ne saurait exposer clairement.
Whismeril 11442 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 26 avril 2018 Dernière intervention - 7 oct. 2016 à 06:26
Bonjour
Commenter la réponse de ucfoutu
Samcher 4 Messages postés jeudi 6 octobre 2016Date d'inscription 7 octobre 2016 Dernière intervention - 7 oct. 2016 à 09:59
0
Utile
Désolée, je suis encore nouvelle sur ce forum. Voilà ce que j'utilise:

Option Private Module
Option Base 1 'pour commencer à 1 au lieu de 0

Public Function Matrice_inverse(M() As Double, size As Integer) As Double()

'fonction calculant l'inverse d'une matrice à partir de l'algorithme (pivot de Gauss)

Dim M_Id() As Double, MInv() As Double
Dim Tempo As Double, pivot As Double

'Vérification que la matrice est carrée

If UBound(M, 2) <> UBound(M, 1) Then MsgBox "La matrice n'est pas carrée !"
    
'Représentation de Gauss, création de la matrice composée par M et la matrice identité à sa droite (size*2size)
    
ReDim M_Id(size, 2 * size)
For i = 1 To size
    For j = 1 To size
        M_Id(i, j) = M(i, j)
        If i = j Then
            M_Id(i, j + size) = 1
        Else
            M_Id(i, j + size) = 0
        End If
    Next
Next

'Traitement de Gauss sur la matrice M_Id() pour inverser la matrice M()

For j = 1 To size 'Partir de la première colonne
    i = j 'Partir de la première ligne
    ' trouve le pivot maximum

Max = 0
For k = i To size
    If Abs(M_Id(k, j)) > Max Then
    imax = k
    Max = Abs(M_Id(k, j))
    End If
Next
If Max = 0 Then MsgBox "La matrice n'est pas inversible !"

i = imax
    pivot = M_Id(i, j)
    
    'Echanger avec la jème ligne si la colonne et la ligne sont différentes
    If j <> i Then
        'Permuter les lignes si elles sont différentes
        For k = j To 2 * size
            Tempo = M_Id(j, k)
            M_Id(j, k) = M_Id(i, k) / pivot 'rendre le pivot égal à 1
            M_Id(i, k) = Tempo
        Next
    Else
        'rendre le pivot égal à 1
        For k = j To 2 * size
            M_Id(j, k) = M_Id(j, k) / pivot
        Next
    End If
    
    'Annulation de tous les coefficients après le pivot
    For i = j + 1 To size
        'Après
        If M_Id(i, j) <> 0 Then
            Tempo = M_Id(i, j)
            For k = j To 2 * size
                M_Id(i, k) = M_Id(i, k) - M_Id(j, k) * Tempo
            Next
        End If
    Next
Next
For j = size To 2 Step -1
    For i = 1 To j - 1
        If M_Id(i, j) <> 0 Then
            Tempo = M_Id(i, j)
            For k = j To 2 * size
                M_Id(i, k) = M_Id(i, k) - M_Id(j, k) * Tempo
            Next
        End If
    Next
Next
'Remplir la matrice inverse à partir de la partie droite de la matrice M-Id et retourner le résultat

ReDim MInv(size, size)

For i = 1 To size
    For j = 1 To size
        MInv(i, j) = M_Id(i, j + size)
    Next
Next

Matrice_inverse = MInv
    
End Function

Public Sub multiplication(M1() As Double, M2() As Double, M3() As Double)

Dim dimL1 As Long, dimC1 As Long
Dim dimL2 As Long
    
    dimL1 = UBound(M1, 1)
    dimC1 = UBound(M1, 2)
    dimL2 = UBound(M2, 1)

    
    If dimC1 <> dimL2 Then
        MsgBox "les dimensions des deux matrices sont incompatibles"
    End If
    
    ReDim M3(dimL1)
    For i = 1 To dimL1
            M3(i) = 0
            For k = 1 To dimC1
                M3(i) = M3(i) + M1(i, k) * M2(k)
            Next
    Next
End Sub
Commenter la réponse de Samcher
ucfoutu 18039 Messages postés lundi 7 décembre 2009Date d'inscriptionModérateurStatut 11 avril 2018 Dernière intervention - Modifié par ucfoutu le 7/10/2016 à 13:52
0
Utile
3
Lorsque l'inverse d'une matrice inverse de la matrice Matrice ne retourne pas la matrice Matrice, cela veut dire que la fonction d'inversion d'une matrice n'est pas bonne. Et cela relève de la connaissance mathématique avant de relever du développement
Puis-je te faire au passage remarquer que VBA dispose (je t'en ai parlé plus haut, non ?) d'une fonction "toute faite" d'inversion de matrice ?


________________________
Nul ne saurait valablement coder ce qu'il ne saurait exposer clairement.
Samcher 4 Messages postés jeudi 6 octobre 2016Date d'inscription 7 octobre 2016 Dernière intervention - 7 oct. 2016 à 14:35
L'algorithme me semble correct, voici un lien de cours sur la résolution de gauss: http://www.math.univ-toulouse.fr/~rau/maths%20appro/retro/c3.pdf
J'ai essayé, avec le même exemple du lien, de calculer l'inverse de l'inverse et j'ai retrouvé la matrice initiale, mais quand je déclare une matrice de type double cela ne marche pas.
Avant de partir sur cette méthode, j'ai utilisé worksheetfunction.Minverse (c'étais la première solution que j'ai trouvée) et on m'affichait comme erreur: impossible de lire la propriété minverse de la classe worksheetfunction!
Et d'ailleurs cette fonction n'est pas assez précise! je me trompe?
ucfoutu 18039 Messages postés lundi 7 décembre 2009Date d'inscriptionModérateurStatut 11 avril 2018 Dernière intervention > Samcher 4 Messages postés jeudi 6 octobre 2016Date d'inscription 7 octobre 2016 Dernière intervention - 7 oct. 2016 à 14:54
Lu dans l'aide VBA :
Certaines matrices carrées ne peuvent pas être inversées et renvoient la valeur d'erreur #NUM! avec la fonction MINVERSE. Le déterminant pour une matrice non inversible est 0.

Nul ne saurait par exemple déterminer la matrice inverse de :
0 1
0 2
Samcher 4 Messages postés jeudi 6 octobre 2016Date d'inscription 7 octobre 2016 Dernière intervention > ucfoutu 18039 Messages postés lundi 7 décembre 2009Date d'inscriptionModérateurStatut 11 avril 2018 Dernière intervention - 7 oct. 2016 à 15:16
la matrice est tout simplement non inversible
Commenter la réponse de ucfoutu
ucfoutu 18039 Messages postés lundi 7 décembre 2009Date d'inscriptionModérateurStatut 11 avril 2018 Dernière intervention - Modifié par ucfoutu le 8/10/2016 à 01:22
0
Utile
L'inverse de TA matrice inverse te retourne en effet bien la matrice de départ.
La matrice inverse que retourne ta fonction est par ailleurs la bonne et celle que retourne la méthode Worksheetfunction.Minverse.

Je ne comprends du coup pas où se situe ton problème et aimerais vraiment que tu nous montres ce que je t'ai demandé plus haut, à savoir où et comment tu as déclaré la matrice de départ. Et aussi, maintenant, comment tu l'as abondée et (enfin) par quelle ligne de code tu appelles ta fonction.

EDIT : tu as écrit :
Avant de partir sur cette méthode, j'ai utilisé worksheetfunction.Minverse (c'étais la première solution que j'ai trouvée) et on m'affichait comme erreur: impossible de lire la propriété minverse de la classe worksheetfunction

Il se trouve que mininverse n'est pas une "propriété", mais une méthode.
Montre comment tu as tenté de l'utiliser.

J'appelle par ailleurs ton attention sur un point qui concerne toutes les méthodes de WorkSheetFunction :
on obtient entre autres ce genre d'erreur ("impossible de lire .....") si les valeurs passées sont issues de formules posant problème et conduisant à une valeur d'erreur (comme #VALEUR, etc ...) ou qui utilisent des références circulaires.

________________________
Nul ne saurait valablement coder ce qu'il ne saurait exposer clairement.
Commenter la réponse de ucfoutu
ucfoutu 18039 Messages postés lundi 7 décembre 2009Date d'inscriptionModérateurStatut 11 avril 2018 Dernière intervention - Modifié par ucfoutu le 8/10/2016 à 08:33
0
Utile
De bon matin :
Je viens de relire lentement ton premier message et en particulier ce passage :
et j'y fais appel dans une autre macro dans laquelle je déclare la matrice A et puis je calcule le vecteur B par une simple multiplication. A chaque fois que j'exécute ma macro, ça me donne des valeurs différentes de A^-1 et B.

un peu embrouillé, mais je commence à me demander si ton "autre macro" n'est pas ta procédure Multiplication et si par "à chaque fois que j'exécute ma macro", tu veux dire que tu la lances plusieurs fois de suite.
Je ne vois pas dans ton code quels paramètres du lui passes (le code d'appel de cette procédure). J'observe que tu lui passes ces paramètres par référence (ByRef par défaut) .

Au fait : quelle est la nécessité du paramètre size, qui n'est autre que le Ubound de la matrice originelle (après avoir bien entendu vérifié comme tu le fais qu'elle est bien carrée) ?

J'observe également que tu as utilisé l'option Private Module (qui fait que sont publiques - et donc toutes susceptibles d'être modifiées depuis n'importe quel endroit de ton projet - toutes les variables non expressément déclarées comme Private dans ce module)

________________________
Nul ne saurait valablement coder ce qu'il ne saurait exposer clairement.
Commenter la réponse de ucfoutu

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.