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 :

Votre avis pour améliorer mon code (opérations matricielles)


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 42
    Par défaut Votre avis pour améliorer mon code (opérations matricielles)
    Bonjour,

    Je suis débutant en C et également nouveau sur ce forum, c'est pour cette raison que j'aurais voulu avoir des conseils pour l'amélioration de mes codes.
    Mon projet consiste, à terme, à réaliser un programme d'ajustement de courbe expérimental avec équations théoriques, pour une application dans le domaine de la physique. J'ai choisis la méthode des moindres carrées pour réalisé mon projet : http://fr.wikipedia.org/wiki/M%C3%A9...es_carr%C3%A9s
    et plus particulièrement la méthode matricielle.

    J'ai donc redéfinie des fonctions qui opère sur des matrices, j'en ai fais trois, une qui transpose la matrice, une permettant effectuer des produits de matrices, et la dernière qui fais l'inverse de la matrice par la méthode du pivot de Gauss.

    Je vais donc commencer par mettre ici mon code de transposée, pour avoir quelques conseils sur celui ci :

    Mon main :

    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
    #include <stdio.h>
     
    #include <stdlib.h>
    #include <math.h>
     
    #include "fonctions.h"
     
     
     
    int main()
     
    {
        int nbreligneA = 0, nbrecolonneA = 0, i = 0, j = 0;
     
        //Valeurs test :
     
        nbreligneA = 3;
        nbrecolonneA = 2;
     
     
        //Matrice A et T
     
        double **A = malloc(nbreligneA * sizeof(double));
        for (i = 0; i < nbreligneA; i++)
        {
            A[i] = malloc(nbrecolonneA*sizeof(double));
        }
     
        double **T ;
     
     
        //Valeurs test(suite) :
     
        A[0][0] = 1;
        A[0][1] = 2;
        A[1][0] = 3;
        A[1][1] = 4;
        A[2][0] = 5;
        A[2][1] = 6;
     
     
        //Création des structures pour ces matrices
     
        Matrice As = {A, nbreligneA, nbrecolonneA};
        Matrice Ts = {T, 0, 0};
     
        //Creation pointeurs vers ces structures
     
        Matrice *pAs = &As;
        Matrice *pTs = &Ts;
     
        //Envois de ces pointeurs à la fonction Transposée
     
        Transposee(pAs, pTs);
     
        //Affichage provisoire de l'essais
     
        for (i = 0; i < As.nbreligne; i++)
        {
            printf("\n|");
     
            for (j = 0; j < As.nbrecolonne; j++)
            {
                printf(" %f", As.matrice[i][j]);
            }
     
            printf(" |");
     
        }
     
        printf("\n\n");
     
        for (i = 0; i < Ts.nbreligne; i++)
        {
            printf("\n|");
     
            for (j = 0; j < Ts.nbrecolonne; j++)
            {
                printf(" %f ", Ts.matrice[i][j]);
            }
     
            printf(" |");
        }
     
        //On libère l'espace pour les matrice A et T
     
        for (i = 0; i < nbreligneA; i++)
        {
            free(A[i]);
        }
        free(A);
     
        for (i = 0; i < Ts.nbreligne; i++)
        {
            free(Ts.matrice[i]);
        }
        free(Ts.matrice);
     
        return 0;
     
    }
    Ma fonction :

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
     
    #include "fonctions.h"
     
    struct Matrice *Transposee(struct Matrice *A, struct Matrice *T)
    {
        int i = 0, j = 0;
     
        //Allocation pour matrice provisoir de travail
     
        double **Ap = malloc(A->nbreligne*sizeof(double));
        for (i = 0; i < A->nbreligne; i++)
        {
            Ap[i] = malloc(A->nbrecolonne*sizeof(double));
        }
     
        //Structure de matrice provisoire
     
        Matrice Aps = {Ap, A->nbreligne, A->nbrecolonne};
     
        //Copie Matrice A dans Ap
     
        for (i = 0; i < Aps.nbreligne; i++)
        {
            for (j = 0; j < Aps.nbrecolonne; j++)
            {
                Ap[i][j] = A->matrice[i][j];
            }
        }
     
        //Allocation de T en fonction de A (ou Aps puisque copie)
     
        T->matrice = malloc(Aps.nbrecolonne*sizeof(double));
        for (i = 0; i < Aps.nbrecolonne; i++)
        {
            T->matrice[i] = malloc(Aps.nbreligne*sizeof(double));
        }
     
        //On remplace le nombre de lignes et de colonnes dans la structure Ts présente dans le main
     
        T->nbreligne = Aps.nbrecolonne;
        T->nbrecolonne = Aps.nbreligne;
     
     
        //Transposé à partir de la matrice provisoire
     
        for (i = 0; i < T->nbreligne; i++)
        {
            for (j = 0; j < T->nbrecolonne; j++)
            {
                T->matrice[i][j] = Aps.matrice[j][i];
            }
        }
     
        //On libère l'espace de la matrice Ap
     
        for (i = 0; i < Aps.nbreligne; i++)
        {
            free(Aps.matrice[i]);
        }
        free(Aps.matrice);
     
        //On retourne T pointeur vers la matrice d'accueil du résultat
     
        return T;
    }
    et les structures et prototypes :

    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
    #ifndef FONCTIONS_H_INCLUDED
     
    #define FONCTIONS_H_INCLUDED
     
    //Protos
     
    struct Matrice *Transposee(struct Matrice *A, struct Matrice *T);
     
     
    //Structures
     
     
    typedef struct Matrice Matrice;
    struct Matrice
    {
        double **matrice;
        int nbreligne;
        int nbrecolonne;
    };
     
     
     
    #endif // FONCTIONS_H_INCLUDED
    Voilà, je remercie d'avance ceux qui me lirons, et les remercies pour leur éventuel conseils.

  2. #2
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    --
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        int nbreligneA = 0, nbrecolonneA = 0, i = 0, j = 0;
    Ces initialisations sont inutiles et non pertinentes puisque soit ces valeurs sont changées quelques lignes plus loin, soit elles sont utilisées comme compteur de boucles dans un for et sont initialisées à ce moment là.
    Je ne suis pas partisan des initialisations systématiques (contrairement à d'autres personnes) mais uniquement lorsqu'elles sont utiles (notamment parce que (1) ça empêche certains warnings du compilateur et (2) ça peut éviter au programme de planter franchement si la véritable initialisation n'a pas été faite (3) ça peut tromper le lecteur en fournissant une information fausse)

    -- Ceci est faux
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       double **A = malloc(nbreligneA * sizeof(double));
    on devrait avoir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
       double *A = malloc(nbreligneA * sizeof(double));
    // ou
       double **A = malloc(nbreligneA * sizeof(double*));
    (en fait, c'est le second cas dans ton code)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        Matrice *pAs = &As;
        Matrice *pTs = &Ts; 
        //Envois de ces pointeurs à la fonction Transposée 
        Transposee(pAs, pTs);
    Je ne suis pas non plus partisan de créer des pointeurs inutilement qui obligent le lecteur à retrouver leur valeur. Personnellement, je préfère ici
    -- Je conseille de structurer un peu le code :

    - Faire une fonction pour construire une Matrice et en profiter pour la coder correctement en testant les allocations.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Matrice * CreerMatrice(int nbreligne,int nbrecolonne)
    {
        double **A = malloc(nbreligne * sizeof(double *));
        // et tester toutes les allocations 
        // En cas d'échec d'une allocation : 
        // libérer les allocations réussies et renvoyer NULL
    /*    for (i = 0; i < nbreligne; i++)
        {
            A[i] = malloc(nbrecolonne*sizeof(double));
        }*/
    return A;
    - Faire une fonction de destruction d'une Matrice
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void DetruireMatrice(Matrice * matrice)
    {
       if(matrice != NULL)
    ....
    }
    - Faire une fonction d'affichage d'une Matrice
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void AfficheMatrice(Matrice * matrice, FILE * out)
    {
       if(matrice != NULL)
    ....
    }
    Le main() devient alors :
    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
    int main(void) 
    {
      Matrice * T;  
      Matrice * A = CreerMatrice(3,2);
      if(A != NULL)
      {
        A[0][0] = 1;
        A[0][1] = 2;
        A[1][0] = 3;
        A[1][1] = 4;
        A[2][0] = 5;
        A[2][1] = 6;
        AfficheMatrice(A,stdout);
        T = Transposee(A);
        AfficheMatrice(T,stdout);
        DetruireMatrice(A);
        DetruireMatrice(T);
      }   
    }
    Avec la fonction Transposee() (pourquoi passer par une Matrice temporaire ??) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Matrice *Transposee(Matrice *A)
    {
       Matrice * T = NULL;  
       if(A != NULL)
       {
          T = CreerMatrice( A->nbrecolonne, A->nbreligne);
          if(T != NULL)      
             for (i = 0; i < T->nbreligne; i++)
                for (j = 0; j < T->nbrecolonne; j++) T->matrice[i][j] = A->matrice[j][i];
       }
       return T;
    }

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Août 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 42
    Par défaut
    Merci beaucoup diogene d'avoir pris le temps de répondre avec autant de détails, je vais m'efforcer de corriger tout cela, dans les deux autres codes aussi, puisqu'il sont codé sur le même exemple.

    Pour ce qui est de la matrice provisoire elle était là, (si je le souvient bien, je l'ai codé il y a un petit moment), pour permettre d'effectuer la transposée de la transposée, bien entendu faire cela n'a pas grand intérêt mais c'était pour s'entrainer à coder une fonction qui pouvais se prendre en paramètre. Mais peu être que cette matrice temporaire est inutile même dans ce cas ... je vais y réfléchir.

    Merci encore.


    Edit : J'ai juste une petite question, peu être idiote, mais si je n'envoies pas en paramètre un pointeurs vers une matrice qui recueil ma transposé, et que ma transposé renvois comme dans ton exemple un pointeur sur une structure créé dans la fonction, je ne comprend pas comment dans le main on retrouve cette structure comprenant la matrice, n'est telle pas supprimé au moment de la sortie de la fonction (puisque créé via malloc dans cette fonction) ? Ou alors le malloc permet de garder tout cela en mémoire entre temps ... ? J'aurais besoin qu'on éclaire ma lanterne sur ce point.

  4. #4
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    - Les variables en allocation automatique (variables locales) sont créées à l'entrée du bloc {} où elles sont définies et seront détruites en sortie du bloc.

    - Les variables en allocation statique (variables globales ou variables déclarées static) sont créées au lancement du programme et seront détruites en fin d'exécution du programme

    - Les variables en allocation dynamique sont créées par malloc() (ou consoeurs) et ne sont détruites que par appel à free(). Ce sont les seules qui demandent une création/destruction explicite.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Août 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 42
    Par défaut
    D'accord merci beaucoup, c'était un point un peu obscur pour moi, ça devrais me permettre de réalisé les choses bien plus simplement normalement.

    Je reposte lorsque j'aurais modifié tout cela.

  6. #6
    Invité
    Invité(e)
    Par défaut
    on devrait avoir
    Code :

    double *A = malloc(nbreligneA * sizeof(double));
    // ou
    double **A = malloc(nbreligneA * sizeof(double*));

    (en fait, c'est le second cas dans ton code)
    Je crois qu'il vaudrait mieux écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      double **A = (double**)malloc(nbreligneA * sizeof(double*));

Discussions similaires

  1. [Débutant] idée pour améliorer mon code ?
    Par Imène_23 dans le forum MATLAB
    Réponses: 7
    Dernier message: 27/08/2011, 23h54
  2. avis pour améliorer mon cv
    Par Nath_k dans le forum CV
    Réponses: 4
    Dernier message: 20/09/2009, 12h45
  3. Réponses: 30
    Dernier message: 05/08/2009, 19h25
  4. [CV] Avis pour améliorer mon cv
    Par lapanne dans le forum CV
    Réponses: 7
    Dernier message: 17/10/2007, 15h04
  5. Réponses: 4
    Dernier message: 26/04/2006, 14h36

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