Résolution matricielle

Samcher Messages postés 4 Date d'inscription jeudi 6 octobre 2016 Statut Membre Dernière intervention 7 octobre 2016 - 6 oct. 2016 à 21:11
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 - 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?!

6 réponses

Whismeril Messages postés 19022 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 17 avril 2024 656
6 oct. 2016 à 21:48
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
1
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
Modifié par ucfoutu le 7/10/2016 à 00:31
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.
0
Whismeril Messages postés 19022 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 17 avril 2024 656
7 oct. 2016 à 06:26
Bonjour
0
Samcher Messages postés 4 Date d'inscription jeudi 6 octobre 2016 Statut Membre Dernière intervention 7 octobre 2016
7 oct. 2016 à 09:59
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
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
Modifié par ucfoutu le 7/10/2016 à 13:52
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.
0
Samcher Messages postés 4 Date d'inscription jeudi 6 octobre 2016 Statut Membre Dernière intervention 7 octobre 2016
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?
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211 > Samcher Messages postés 4 Date d'inscription jeudi 6 octobre 2016 Statut Membre Dernière intervention 7 octobre 2016
Modifié par ucfoutu le 7/10/2016 à 15:00
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
0
Samcher Messages postés 4 Date d'inscription jeudi 6 octobre 2016 Statut Membre Dernière intervention 7 octobre 2016 > ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018
7 oct. 2016 à 15:16
la matrice est tout simplement non inversible
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
Modifié par ucfoutu le 8/10/2016 à 01:22
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.
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
Modifié par ucfoutu le 8/10/2016 à 08:33
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.
0
Rejoignez-nous