IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

résoudre Ax=b avec A matrice triangulaire inférieure


Sujet :

C++

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France, Doubs (Franche Comté)

    Informations forums :
    Inscription : Novembre 2010
    Messages : 4
    Points : 1
    Points
    1
    Par défaut résoudre Ax=b avec A matrice triangulaire inférieure
    Bonjour,
    je suis actuellement en L3 maths appliquées, je débute en C++ et j'ai un projet à faire dont la première question est de résoudre le système Ax=b avec A matrice triangulaire inférieure. j'ai fait le programme suivant mais il ne veut pas marcher, je ne comprend pas pourquoi, est ce que quelqu'un pourrait m'aider? merci.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    #include <cstdlib>
    #include <iostream>
     
    using namespace std;
     
    void AfficherMatrice(float **M, int n){ //affiche une matrice de taille n*n
         for (int i=0; i<n; i++){
             for (int j=0; j<n; j++){
                 cout<< M[i][j] << "\t" ;
                 }
                 cout<< endl;
                 }
                 }
     
    void AfficherVecteur (float *y, int n){ //affiche un vecteur de taille n
         for (int i=0; i<n; i++){
             cout<< y[i] << "\t";
             }
             cout<<endl;
             }
     
    void MTI(float **M, int n){ // matrice triangulaire inférieure
                    for(int i=0; i<n; i++){ 
                 for (int j=0; j<=i; j++){
                     cout<<M[i][j]<< "\t";
                     }
                     cout<<endl;
                     }
                     }
     
    float Somme(float **M, float *x, int i, int j){ // M.x
         float S=0;
         for (i=1; i<j;i++){
             S+=M[j][i]*x[i];
             }
             }
     
    void SystMatTI (float **M, float *b, float *x, int n){ //trouver x tel que Mx=b avec M tiangulaire inférieure
         x[1]=b[1]/M[1][1];
         for (int j=2; j<=n; j++){
                 x[j]=(b[j]- Somme(M,x,1,j-1))/M[j][j];
                 }
                 }
     
     
     
    int main(int argc, char *argv[])
    {
        int n;
        cout << "entrer la valeur de n" <<endl;
        cin>>n;
        float **A=NULL;
        A= new float*[n];
        for (int i=0; i<n; i++){
            A[i]= new float[i+1];
            }
            for (int i=0; i<n; i++){
                for (int j=0; j<n; j++){
       cout<< "Entrer A" <<i+1<<","<<j+1<<endl;
       cin>> A[i][j];
    }
    }
       AfficherMatrice(A,n);
       cout<<endl;
       MTI(A,n);
       float *x;
       x=new float [n];
       float *b=NULL;
       b= new float [n];
           for (int i=0; i<n; i++){
               cout<< "Entrer b" <<i+1<< endl;
               cin>>b[i];
               }
               AfficherVecteur(b,n);
               cout<<endl;
               SystMatTI(A,b,x,n);
               cout<<endl;
     
       for (int i=0; i<n; i++){
           delete []A[i];
           }
           delete []A;
           delete []b;
           delete []x;
           x=NULL;
     
        system("PAUSE");
        return EXIT_SUCCESS;
    }

  2. #2
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    Oulà, c'est loin les calculs sur les matrices…
    Je ne vais probablement pas pouvoir t'aider beaucoup sur le fond, juste sur le code.
    Par contre, ce serait sympa de faire attention à l'indentation ; bien réalisée elle facilite (de beaucoup) la lecture et la compréhension du code.

    Pour commencer, j'aimerais pointer un gros problème.
    Tu construis ta matrice A comme une matrice triangulaire inférieure.
    Jusque là, pas de souci.
    Mais après, tu veux l'afficher avec ta fonction « AfficherMatrice() », qui s'attend à recevoir une matrice complète.
    Et donc, à chaque fois que tu tentes d'accéder à M[i][j] alors que j > i, tu vas dans une zone mémoire qui n'a pas été réservée pour la ligne en cours.
    Ça peut être n'importe quoi : une zone non initialisée, une case d'une autre ligne de ta matrice, une zone réservée pour une autre variable, une zone à laquelle tu n'es pas censée avoir accès…

    Bon, ce n'est pas dramatique puisque tu ne fais qu'accéder à cette zone, tu n'essaies pas d'en modifier le contenu.
    Au pire, ça affichera n'importe quoi.
    Mais il faut bien que tu te rendes comptes que tu tentes d'accéder à une case qui finalement se trouve hors de ta matrice.
    Cela peut être critique si tu essaies d'en modifier le contenu…

    Ensuite, ta fonction « Somme() » est censée retourner un « float », mais ne retourne rien.
    Je suppose que c'est un juste oubli de ta part, et que normalement tu retournes « S ».
    Ceci dit, dans la boucle, la première valeur de «i » devrait être «0 », non ?

    Voilà, après je n'ai pas vu d'autres choses importantes.
    Bonne continuation !

  3. #3
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France, Doubs (Franche Comté)

    Informations forums :
    Inscription : Novembre 2010
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    ok merci j'ai fait quelques modifs mais en fait ce que je veux c'est qu'après exécution il me donne le vecteur x et ça marche pas (j'ai remplacé void par float dans ma fonction SystMTI), il affiche bien la matrice triangulaire inférieure et le vecteur b mais après il me met "a cessé de fonctionner" donc je pense que c'est ma fonction qui est fausse seulement je ne vois pas pourquoi.
    désolée d'être aussi nulle

  4. #4
    Membre chevronné Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 043
    Points : 2 234
    Points
    2 234
    Par défaut
    Évite un maximum les pointeurs. Ta matrice n'est pas obligé d'être une allocation dynamique.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    float **A=NULL;
    A= new float*[n];
    //peut être remplacer par
    float A[n];
     
    //Ainsi que 
    float *x;
    x=new float [n];
    //peut être remplacer par
    float x[n];
    Il n'est pas plus efficace de passer une type de base (int, float, etc...) par pointeur que par valeur. Si tu dois la modifier, passe le par référence au pire.
    Déjà ça éclaircira ton code.
    A quel ligne plante-t-il exactement?
    Homer J. Simpson


  5. #5
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France, Doubs (Franche Comté)

    Informations forums :
    Inscription : Novembre 2010
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Le soucis c'est qu'on me demande d'utiliser les pointeurs justement!
    à la compilation il ne me met aucun problème mais après il plante pour m'afficher le vecteur x.

  6. #6
    Membre chevronné
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Points : 1 921
    Points
    1 921
    Par défaut http://solutions-entreprise.developpez.com/
    1/ on alloue les tableaux 2D proprement:
    http://codepad.org/K2WAwRBP

    2/ tes boucles ont des bornes bizarres ...

  7. #7
    Membre éprouvé Avatar de cs_ntd
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2006
    Messages
    598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2006
    Messages : 598
    Points : 1 214
    Points
    1 214
    Par défaut
    Ca c'est du C Joel-F. Il vaut mieux utiliser les new/delete en C++, et éviter les cast sauvages du genre (type)var...

    Sinon pour le code, j'ai relevé quelques erreurs, voici une version ou je pointe ce qui ne va pas (comentaires en gras) (les commentaires sur les index 0, c'est juste une hypothèse, j'ai pas vérifié l'algo) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    #include <cstdlib>
    #include <iostream>
    
    using namespace std;
    
    void AfficherMatrice(float **M, int n)
    { //affiche une matrice de taille n*n
        for (int i=0; i<n; i++)
        {
            for (int j=0; j<n; j++)
            {
                cout<< M[i][j] << "\t" ;
            }
            cout<< endl;
         }
    }
    
    void AfficherVecteur (float *y, int n)
    { //affiche un vecteur de taille n
        for (int i=0; i<n; i++)
        {
            cout<< y[i] << "\t";
        }
        cout<<endl;
    }
    
    void MTI(float **M, int n)
    { // matrice triangulaire inférieure
        for(int i=0; i<n; i++)
        {
            for (int j=0; j<=i; j++)
            {
                cout<<M[i][j]<< "\t";
            }
            cout<<endl;
        }
    }
    
    float Somme(float **M, float *x, int i, int j)
    { // M.x
        float S=0;
        //Toujours pas d'index 0 ?    for (i=1; i<j;i++)
        {
            S+=M[j][i]*x[i];
        }
        return S; 
        //Retourner quelque chose, je ne sais pas
        //si c'est S simplement;}
    
    void SystMatTI (float **M, float *b, float *x, int n)
    { //trouver x tel que Mx=b avec M tiangulaire inférieure
    
        //Pourquoi jamais index 0 ?
    
        x[1]=b[1]/M[1][1];
        
        //!!! j<n !!! les plantages viennent de là !
        //Là, tu déborde de b, de la matrice, etc... des zones non allouées !!
        for (int j=2; j<n; j++)
        {
            x[j]=(b[j]- Somme(M,x,1,j-1))/M[j][j]; 
            //Est tu sûr que M[j][j] != 0 ?
            //Si jamais = 0 ça va planter 
            //du genre "a cesser de fonctionner..."
            //A toi de prévoir le cas...
        }
    }
    
    
    
    int main(int argc, char *argv[])
    {
        int n;
        cout << "entrer la valeur de n" <<endl;
        cin>>n;
    
        float** A = new float* [n]; //Pas besoin de la macro NULL
    
        for (int i=0; i<n; i++)
        {
            A[i]= new float[n];
            //Problème : tu veux que A soit une vrai matrice (n*n), mais
            //tu n'alloue qu'une matrice triangulaire
        }
    
        for (int i=0; i<n; i++)
        {
            for (int j=0; j<n; j++)
            {
                cout<< "Entrer A" <<i+1<<","<<j+1<<endl;
                cin>> A[i][j];
            }
        }
    
        AfficherMatrice(A,n);
        cout<<endl;
        MTI(A,n);
        //float *x = new float [n];
        //Pourquoi pas :
        float x[n];
    
        //float *b = new float [n];
        //Idem
        float b[n];
    
        for (int i=0; i<n; i++)
        {
            cout<< "Entrer b" <<i+1<< endl;
            cin>>b[i];
        }
    
        AfficherVecteur(b,n);
        cout<<endl;
    
        SystMatTI(A,b,x,n);
        cout<<endl;
    
        //Afficher le résultat peut-être ?
        AfficherVecteur(x,n);
    
        for (int i=0; i<n; i++)
        {
            delete[] A[i];
        }
        delete[] A;
        delete[] b;
        delete[] x;
    
        //OK, les desalloc sont bonnes
    
        //x=NULL; : Inutile...
    
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    Normalement, ça ne plante plus. Quand à faire ce que tu veux (au niveau de l'algo), je n'ai pas vérifié.

    Mais les plantages que tu a eu démontrent tout l'intéret de ne pas utiliser les tableaux bas-niveaux en C++ (qu'ils restent en C), mais d'utiliser des structures "toutes prêtes" venant de la STL, du genre std::vector, std::list, etc... qui prennent en charge les débordements d'index, et évitent de planter sauvagement...

    The magic of Opera, La magie de l'Opera
    The mysteries of Space Opera, Les mystères de l'Opera Spatial
    Mr. Know-it-all, M. Je-Sais-Tout
    Prelude in C sharp minor, the most beautiful piano song and the best C sharp prelude ever, Prélude en do dièse mineur, le plus beau morceau de piano et le meilleur prélude au C#
    The Mesmerizing Saphir Division for Nerds, L'Hypnotisante Division Saphire pour les Nerds (HDSN)

  8. #8
    Membre chevronné
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Points : 1 921
    Points
    1 921
    Par défaut
    Citation Envoyé par cs_ntd Voir le message
    Ca c'est du C Joel-F. Il vaut mieux utiliser les new/delete en C++, et éviter les cast sauvages du genre (type)var...
    Ouais je viens de voir que j'ai pas mit le bon lien. J'édite.
    J'ai du etre trompé par le code initial :€

    Le bon lien: http://codepad.org/nDy8z2iG

    Sinon, il faut vraiment éviter les allcoations 2D disjointes, ce que vector< vector<> > propose, le cache n'aime vraiment, vraiment pas. L'allocation NRC n'ets pas plus dur à mettre en place.

  9. #9
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    La problématique n'est pas justement de traiter une matrice triangulaire inférieur et donc de ne pas allouer la totalité ligne x colonne ?

  10. #10
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France, Doubs (Franche Comté)

    Informations forums :
    Inscription : Novembre 2010
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    merci pour vos réponse, j'ai enfin réussis à faire quelque chose qui marche avec le code suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    #include <cstdlib>
    #include <iostream>
     
    using namespace std;
     
    void AfficherMatrice(float **M, int n){ //affiche une matrice de taille n*n
         for (int i=0; i<n; i++){
             for (int j=0; j<n; j++){
                 cout<< M[i][j] << "\t" ;
                 }
                 cout<< endl;
                 }
                 }
     
    void AfficherVecteur (float *y, int n){ //affiche un vecteur de taille n
         for (int i=0; i<n; i++){
             cout<< y[i] << "\t";
             }
             cout<<endl;
             }
     
    void MTI(float **M, int n){ // matrice triangulaire inférieure
                    for(int i=0; i<n; i++){ 
                 for (int j=0; j<=i; j++){
                     cout<<M[i][j]<< "\t";
                     }
                     cout<<endl;
                     }
                     }
     
    float Somme(float **M, float *x, int i, int j){ // M.x
         float S=0;
         for (i=0; i<j;i++){
             S+=M[j][i]*x[i];
             }
             return S;
             }
     
    float SystMatTI (float **M, float *b, float *x, int n){ //trouver x tel que Mx=b avec M tiangulaire inférieure
         x[0]=b[0]/M[0][0];
         for (int j=1; j<n; j++){
                 x[j]=(b[j]- Somme(M,x,0,j))/M[j][j];
                 }
                 }
     
     
     
    int main(int argc, char *argv[])
    {
        int n;
        cout << "entrer la valeur de n" <<endl;
        cin>>n;
        float **A= new float *[n];
        for (int i=0; i<n; i++){
            A[i]= new float[n];
            }
            for (int i=0; i<n; i++){
                for (int j=0; j<=i; j++){
       cout<< "Entrer A" <<i+1<<","<<j+1<<endl;
       cin>> A[i][j];
    }
    }
       MTI(A,n);
       float *x= new float [n];
       float *b= new float [n];
           for (int i=0; i<n; i++){
               cout<< "Entrer b" <<i+1<< endl;
               cin>>b[i];
               }
               AfficherVecteur(b,n);
               cout<<endl;
               SystMatTI(A,b,x,n);
               cout<<endl;
               AfficherVecteur(x,n);
     
       for (int i=0; i<n; i++){
           delete []A[i];
           }
           delete []A;
           delete []b;
           delete []x;
     
        system("PAUSE");
        return EXIT_SUCCESS;
    }

  11. #11
    Membre expérimenté
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Points : 1 685
    Points
    1 685
    Par défaut
    Bonjour,

    Citation Envoyé par 3DArchi Voir le message
    La problématique n'est pas justement de traiter une matrice triangulaire inférieur et donc de ne pas allouer la totalité ligne x colonne ?
    Excellente question!

    Peut-être qu'il faudrait mieux nommer les fonctions, comme par exemple
    Somme -> produitMatriceVecteur
    MTI -> afficherPartieTriangulaireInferieure
    SystMatTI -> resoudreSystemeTriangulaireInferieur

    J'ajouterais dans 'MTI' un petit test d'inversibilité" en vérifiant que le déterminant n'est pas nul, i.e. que tous les coefficients diagonaux sont non nuls. Par exemple, à la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    x[j]=(b[j]- Somme(M,x,0,j))/M[j][j];
    tu dois d'abord vérifier que M[j][j] est différent de zéro avant de diviser.

    Pourquoi ne pas faire une classe pour les vecteurs et une classe pour les matrices triangulaires inférieures? Si tu as vu les classes en cours de C++, je pense que ton prof s'attend à ce que tu les fasses.

  12. #12
    Membre chevronné
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Points : 1 921
    Points
    1 921
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    La problématique n'est pas justement de traiter une matrice triangulaire inférieur et donc de ne pas allouer la totalité ligne x colonne ?
    Ho, dans ce cas il suffit de modifier la fonction alloc pour allouer w - i éléments par lignes au lieu de w.

    Le bloc reste continue avec une structure type LAPACK

    [ a 0 0 0]
    [ b c 0 0] => [a | b c | d e f | g h i j]
    [ d e f 0]
    [ g h i j ]

    L'astuce NRC reste valable

Discussions similaires

  1. Réponses: 3
    Dernier message: 27/01/2007, 17h53
  2. Calculer une moyenne avec une matrice
    Par progfou dans le forum Algorithmes et structures de données
    Réponses: 5
    Dernier message: 05/06/2006, 16h47
  3. [numarray] Image convolué avec une matrice.
    Par parp1 dans le forum Calcul scientifique
    Réponses: 1
    Dernier message: 20/04/2006, 17h35
  4. [SWING] remplir une jtable avec une matrice de double
    Par Psykorel dans le forum Composants
    Réponses: 3
    Dernier message: 04/01/2006, 14h14
  5. [JTable] remplir avec une matrice
    Par ybdz dans le forum Composants
    Réponses: 3
    Dernier message: 08/12/2004, 21h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo