Inversion de matrice - résolution de systèmes d'équations linéaires

Description

Il est souvent pratique de résoudre des systèmes d'équations linéaires.
Je me suis donc lancé dans l'inversion de matrices.
J'ai utilisé la formule A^(-1) = (1/dét(A))*tcom(A)

Mon code comprend donc :
- une fonction qui calcule le déterminant de matrices carrées
- une procédure pour calculer la transposée
- une procédure pour calculer les matrices mineures (on enlève une ligne et une colonne)
- une procédure de calcul des cofacteurs (=déterminant de la matrice mineure à un coefficient -1 près)
- et finalement une procédure de calcul de la matrice inverse

Enfin, une procédure de multiplication de matrice permet d'obtenir la solution d'un système A*X=B (car B = A^(-1)*B)

Source / Exemple :


Function deter_vb(mat() As Double)
'cette fonction nécessite uniquement une matrice d'entrée carrée : mat()
Dim i As Integer, j As Integer
Dim dim1 As Long, dim1_1 As Long
Dim mat_min() As Double
Dim deter As Double, deter_1 As Double

    'Vérification portant sur la matrice qui doit être carrée
    dim1 = UBound(mat, 1)
    If dim1 <> UBound(mat, 2) Then
        MsgBox "la matrice doit être carrée"
    End If
    'Initialisation de la valeur à 0
    déter = 0
    
    If dim1 = 1 Then
    'si la matrice est de dimension 1, le déterminant est trivialement égal au coef a11
        deter = mat(1, 1)
    Else
    'sinon, il faut décomposer le déterminant en une somme de n déterminants de dimension (n - 1)
        For j = 1 To dim1
            'appel de la procédure de calcul de la comatrice de la matrice d'entrée pour i = 1 et le j en cours
            Call mat_mineur(mat(), 1, j, mat_min(), dim1_1)
            'appel de la procédure de calcul du déterminant de la comatrice (de dimension (n-1))
            deter_1 = deter_vb(mat_min())
            'ajout du terme correspondant au déterminant de la comatrice
            deter = deter + (-1) ^ (1 + j) * mat(1, j) * deter_1
        Next j
    End If
    deter_vb = deter
End Function

Sub mat_mul(mat1() As Double, mat2() As Double, mat3() As Double)
Dim i As Integer, j As Integer, k As Integer
Dim dimx1 As Long, dimy1 As Long
Dim dimx2 As Long, dimy2 As Long
    
    dimx1 = UBound(mat1, 1)
    dimy1 = UBound(mat1, 2)
    dimx2 = UBound(mat2, 1)
    dimy2 = UBound(mat2, 2)
    
    If dimy1 <> dimx2 Then
        MsgBox "les dimensions des deux matrices sont incompatibles"
    End If
    
    ReDim mat3(1 To dimx1, 1 To dimy2)
    For i = 1 To dimx1
        For j = 1 To dimy2
            mat3(i, j) = 0
            For k = 1 To dimx2
                mat3(i, j) = mat3(i, j) + mat1(i, k) * mat2(k, j)
            Next k
        Next j
    Next i
    
End Sub

Sub mat_inverse(mat() As Double, mat_inv() As Double)
Dim i As Integer, j As Integer
Dim dim1 As Long
    
    'Vérification portant sur la matrice qui doit être carrée
    dim1 = UBound(mat, 1)
    If dim1 <> UBound(mat, 2) Then
        MsgBox "la matrice doit être carrée"
    End If
    
    ReDim mat_inv(1 To dim1, 1 To dim1)
    Dim deter As Double
    Dim mat_compl() As Double
    
    deter = deter_vb(mat())
    
    If deter = 0 Then
        MsgBox "la matrice n'est pas inversible car son déterminant est nul !"
    Else
        Call mat_complementaire(mat(), mat_compl())
        
        For i = 1 To dim1
            For j = 1 To dim1
                mat_inv(i, j) = (1 / deter) * mat_compl(i, j)
            Next j
        Next i
    End If
    
End Sub

Sub mat_transposee(mat() As Double, mat_transp() As Double)
Dim i As Integer, j As Integer, k As Integer
Dim dimx As Long, dimy As Long
    
    dimx = UBound(mat, 1)
    dimy = UBound(mat, 2)
    
    ReDim mat_transp(1 To dimy, 1 To dimx)
    For i = 1 To dimy
        For j = 1 To dimx
            mat_transp(i, j) = mat(j, i)
        Next j
    Next i
    
End Sub

Sub mat_complementaire(mat() As Double, mat_compl() As Double)
Dim i As Integer, j As Integer
Dim dim1 As Integer

    'Vérification portant sur la matrice qui doit être carrée
    dim1 = UBound(mat, 1)
    If dim1 <> UBound(mat, 2) Then
        MsgBox "la matrice doit être carrée"
    End If
    
    Dim mat_cof() As Double
    
    Call mat_cofacteur(mat(), mat_cof())
    Call mat_transposee(mat_cof(), mat_compl())
    
End Sub

Sub mat_cofacteur(mat() As Double, mat_cof() As Double)
Dim i As Integer, j As Integer
Dim dim1 As Long, dim2 As Long
Dim deter As Double

    'Vérification portant sur la matrice qui doit être carrée
    dim1 = UBound(mat, 1)
    If dim1 <> UBound(mat, 2) Then
        MsgBox "la matrice doit être carrée"
    End If
    
    Dim mat_min() As Double
    ReDim mat_cof(1 To dim1, 1 To dim1) As Double
    
    For i = 1 To dim1
        For j = 1 To dim1
            'Appel de la procédure de calcul de la matrice mineure de la matrice d'entrée (ligne i et colonne j)
            Call mat_mineur(mat(), i, j, mat_min(), dim2)
            'Appel de la procédure de calcul du déterminant de la comatrice (de dimension (n-1))
            deter = deter_vb(mat_min())
            mat_cof(i, j) = (-1) ^ (i + j) * deter
        Next j
    Next i
    
End Sub

Sub mat_mineur(mat() As Double, lig As Integer, col As Integer, mat_min() As Double, dim2 As Long)
Dim i As Integer, j As Integer
Dim i_co As Integer, j_co As Integer
Dim dim1 As Long
    
    dim1 = UBound(mat, 1)
    dim2 = dim1 - 1
    
    ReDim mat_min(1 To dim2, 1 To dim2)
    i_co = 0
    For i = 1 To dim1
        If i <> lig Then i_co = i_co + 1
        j_co = 0
        For j = 1 To dim1
            If j <> col Then j_co = j_co + 1
            If i <> lig And j <> col Then
                mat_min(i_co, j_co) = mat(i, j)
            End If
        Next j
    Next i
    
End Sub

Conclusion :


Ca semble bien fonctionner sur des cas de matrice simples (comparaison avec les résultats issus des fonctions d'Excel).

Mais n'hésitez pas à me faire part de vos remarques, notamment si vous détectez un problème.

Codes Sources

A voir également

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.