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

MATLAB Discussion :

Simplification d'un code avec des boucles [Débutant]


Sujet :

MATLAB

  1. #1
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 401
    Points : 102
    Points
    102
    Par défaut Simplification d'un code avec des boucles
    Bonjour,

    J'ai quelques questions sur un code que je viens d'écrire. Elles seront plus simples à comprendre pour ceux qui auraient suivi cette discussion

    mais vous pouvez m'aider sans y avoir pris part.

    Voici donc le code :

    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
    function mat=tableau_3(Dreflux_123_liquide,Freflux_123_liquide,valeurs_ph)
     
    mat=[];
    if isempty(Dreflux_123_liquide | Freflux_123_liquide)
       return
    end
     
    %On va créer une matrice mat dont la 1ère colonne comporte les éléments
    %de Dreflux_123 en colonne, la 2ème colonne les éléments de Freflux_123
    %en colonne, la 3ème colonne la valeur du pH correspondant selon les
    %critères définis plus bas, la 4ème colonne l'acidité et la 5ème colonne le
    %type.
     
    %colonnes 1 et 2 de mat : début et fin des événements de reflux
     
    mat(:,1)=Dreflux_123_liquide(:,1)';
    mat(:,2)=max(Freflux_123_liquide(:,2),Freflux_123_liquide(:,3));
     
    %colonne 3 de mat : la valeur du pH pour les événements i.e. la valeur du
    %pH mesuré entre le début et la fin de l'événement.
     
    A=mat(:,1);
    B=mat(:,2);
    mat(:,3)=zeros(size(Dreflux_123_liquide,1),1);
    C=mat(:,3);
    for i=1:size(Dreflux_123_liquide,1)
        C(i)=max(valeurs_ph(A(i):B(i)));
    end
    mat(:,3)=C;
     
    %colonne 4 de mat : le caractère du pH : il est 'a' si pH<=4, 'f-a'
    %si 4<pH<6.8 et 'non-a' si pH>=6.8.
     
    mat(:,4)=zeros(size(Dreflux_123_liquide,1),1);
    D=mat(:,4);
     
    for i=1:size(C,1);
        if (C(i)<=4)
            D(i)='a';
        elseif (4<C(i)<6.8)
            D(i)='f-a';
        else
            D(i)='non-a';
        end
    end
    mat(:,4)=D;
     
    end
    Avec ce code j'ai besoin de créer un tableau mat (une matrice) avec différentes choses. Tout se passe bien jusqu'à la création de la colonne D : là le programme ne fonctionne pas à partir de la boucle for : j'ai besoin de remplir cette colonne D selon la valeur des éléments de la colonne C mais cela ne fonctionne pas de la sorte. C'est gênant, car pour des raisons pratiques, je voudrais qu'il y ait bien des chaînes de caractères dans D. Si je mets à la place des nombres comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    for i=1:size(Dreflux_123_liquide,1);
        if (C(i)<=4)
            D(i)=1;
        elseif (4<C(i)<6.8)
            D(i)=2;
        else
            D(i)=3;
        end
    end
    Cela ne marche toujours pas car la boucle for fait comme si C(i) était toujours compris entre 4 et 6.8 et mets toujours D(i) à 2. Ce serait bien de faire marcher l'une ou l'autre des possibilités même si je préfère la solution avec des chaînes de caractères.

    Enfin, j'utilise une "ruse" pour pouvoir recourir aux colonnes de mat en initialisant par exemple mat(:,3) avec des zéros et en stockant le résultat dans C. Je peux alors utiliser la notation C(i). En effet j'ai essayé avec mat(:,3)(i) mais cela ne fonctionne pas. Peut-on se passer de ceci ?

  2. #2
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 401
    Points : 102
    Points
    102
    Par défaut
    Je pense avoir trouvé pour le problème du vecteur D lorsqu'on utilsie des nombres 1,2,3 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    for i=1:size(Dreflux_123_liquide,1);
        if (C(i)<=4)
            D(i)=1;
        elseif ((C(i)>4) & (C(i)<6.8))
            D(i)=2;
        else
            D(i)=3;
        end
    end
    Cependant je préférais remplir D avec des chaines de caractères. Comment faire ?

    D'autre part, j'ai également besoin d'ajouter une cinquième colonne, disons E, où je définirais le domaine d'étude : liquide, mélange ou gazeux. Pour se faire, j'ai pensé faire la chose suivante : je voudrais lire le premier paramètre de fonction, ici Dreflux_123_liquide et voir par quoi il finit après le second "_", ici c'est "liquide". Tous les premiers vecteurs passés en paramètres seront de cette forme : Dreflux_ijk_domaine et je voudrais donc lire cette chaîne "domaine" et réaliser à nouveau une boucle : si ...=liquide alors E(i)=1 , si ..=melange, alors E(i)=2 mais j'ignore comment le faire par exemple avec inputname qu'on m'avait suggéré ailleurs.

    CORRECTION

    Bon, j'ai réussit à faire le code suivant qui fait ce que je veux :

    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
    function mat=tableau_3(Dreflux_123_liquide,Freflux_123_liquide,valeurs_ph)
     
    mat=[];
    if isempty(Dreflux_123_liquide | Freflux_123_liquide)
       return
    end
     
    %On va créer une matrice mat dont la 1ère colonne comporte les éléments
    %de Dreflux_123 en colonne, la 2ème colonne les éléments de Freflux_123
    %en colonne, la 3ème colonne la valeur du pH correspondant selon les
    %critères définis plus bas, la 4ème colonne l'acidité et la 5ème colonne le
    %type.
     
    %colonnes 1 et 2 de mat : début et fin des événements de reflux
     
    mat(:,1)=Dreflux_123_liquide(:,1)';
    mat(:,2)=max(Freflux_123_liquide(:,2),Freflux_123_liquide(:,3));
     
    %colonne 3 de mat : la valeur du pH pour les événements i.e. la valeur du
    %pH mesuré entre le début et la fin de l'événement.
     
    A=mat(:,1);
    B=mat(:,2);
    mat(:,3)=zeros(size(Dreflux_123_liquide,1),1);
    C=mat(:,3);
    for i=1:size(Dreflux_123_liquide,1)
        C(i)=max(valeurs_ph(A(i):B(i)));
    end
    mat(:,3)=C;
     
    %colonne 4 de mat : le caractère du pH : il est 'a' si pH<=4 (type 1), 'f-a'
    %si 4<pH<6.8 (type 2) et 'non-a' si pH>=6.8 (type 3).
     
    mat(:,4)=zeros(size(Dreflux_123_liquide,1),1);
    D=mat(:,4);
     
    for i=1:size(Dreflux_123_liquide,1);
        if (C(i)<=4)
            D(i)=1;
        elseif ((C(i)>4) & (C(i)<6.8))
            D(i)=2;
        else
            D(i)=3;
        end
    end
    mat(:,4)=D;
     
    %colonne 5 de mat : le domaine du reflux étudié : liquide (type 1), mélange
    %(type 2) ou gazeux (type 3)
     
    mat(:,5)=zeros(size(Dreflux_123_liquide,1),1);
    E=mat(:,5);
     
    %On a besoin de regarder si le vecteur passé en paramètre fini par liquide,
    %melange ou agzeux pour donner le domaine correspondant.
     
    F=inputname(1);
     
    for i=1:size(Dreflux_123_liquide,1);
        if (F(13:end)=='liquide')
            E(i)=1;
        elseif (F(13:end)=='melange')
            E(i)=2;
        else
            E(i)=3;
        end
    end
    mat(:,5)=E;
    end
    On a donc dans mat tout ce dont j'ai besoin. La question est : comment simplifier ce code, notamment se passer de A,B,C...ect et comment mettre des chaînes de caractères dans la matrice telles que 'f-a' 'liquide' ?

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    265
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 265
    Points : 352
    Points
    352
    Par défaut
    tu ne peut pas mettre dans une même matrice des chaine de caractères de taille différentes ( enfin si tu peux mais chaque chaine plus petite sera compléter par des zéros )

    Il faut passer par un tableau de cellule.
    au lieu de faire A(i)='f-a' tu ecrit A{i}='f-a'.

    quand tu souhaitera y accéder utilise la même syntaxe ( =A{i} )

  4. #4
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 401
    Points : 102
    Points
    102
    Par défaut
    Bonjour et merci de ta réponse mais je n'ai pas bien compris ce que tu me proposes de faire. En gros je devrais utiliser une "colonne de cellule" mais comment faire exactement dans mon contexte précis ?

  5. #5
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 401
    Points : 102
    Points
    102
    Par défaut
    Bon disons que peut-être quelqu'un pourra m'aider pour trouver une solution avec les chaînes de caractères, mais en attendant j'ai réalisé une variante avec des nombres. Voici donc la fonction reflux_3 correcte :

    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
    function mat=tableau_3(Dreflux_123_liquide,Freflux_123_liquide,valeurs_ph)
     
    mat=[];
    if isempty(Dreflux_123_liquide | Freflux_123_liquide)
       return
    end
     
    %On va créer une matrice mat dont la 1ère colonne comporte les éléments
    %de Dreflux_123 en colonne, la 2ème colonne les éléments de Freflux_123
    %en colonne, la 3ème colonne la valeur du pH correspondant selon les
    %critères définis plus bas, la 4ème colonne l'acidité et la 5ème colonne le
    %type.
     
    %colonnes 1 et 2 de mat : début et fin des événements de reflux
     
    mat(:,1)=Dreflux_123_liquide(:,1)';
    mat(:,2)=max(Freflux_123_liquide(:,2),Freflux_123_liquide(:,3));
     
    %colonne 3 de mat : la valeur du pH pour les événements i.e. la valeur du
    %pH mesuré entre le début et la fin de l'événement.
     
    A=mat(:,1);
    B=mat(:,2);
    mat(:,3)=zeros(size(Dreflux_123_liquide,1),1);
    C=mat(:,3);
    for i=1:size(Dreflux_123_liquide,1)
        C(i)=max(valeurs_ph(A(i):B(i)));
    end
    mat(:,3)=C;
     
    %colonne 4 de mat : le caractère du pH : il est 'a' si pH<=4 (type 1), 'f-a'
    %si 4<pH<6.8 (type 2) et 'non-a' si pH>=6.8 (type 3).
     
    mat(:,4)=zeros(size(Dreflux_123_liquide,1),1);
    D=mat(:,4);
     
    for i=1:size(Dreflux_123_liquide,1);
        if (C(i)<=4)
            D(i)=1;
        elseif ((C(i)>4) & (C(i)<6.8))
            D(i)=2;
        else
            D(i)=3;
        end
    end
    mat(:,4)=D;
     
    %colonne 5 de mat : le domaine du reflux étudié : liquide (type 1), mélange
    %(type 2) ou gazeux (type 3)
     
    mat(:,5)=zeros(size(Dreflux_123_liquide,1),1);
    E=mat(:,5);
     
    %On a besoin de regarder si le vecteur passé en paramètre fini par liquide,
    %melange ou agzeux pour donner le domaine correspondant.
     
    F=inputname(1);
     
    for i=1:size(Dreflux_123_liquide,1);
     
        if(numel(F(13:end))==7)
     
            if (F(13:end)=='liquide')
            E(i)=1;
            elseif (F(13:end)=='melange')
            E(i)=2;
            end
        else
            E(i)=3;
        end
    end
    mat(:,5)=E;
    end
    J'y ai ajouté quelques corrections : à la fin du code je fais une nouvelle "ruse" lorsque j'examine si la fin de F à partir du 13ème caractère est "liquide", "melange" ou "gazeux". En effet liquide et melange ont même longueur (7 caractères) alors que gazeux a 6 caractères. Je fais donc une distinction sur la longueur afin de m'en sortir.

    La suite de mes questions s'adressent plus particulièrement à Dut mais si vous souhaitez m'aider, tout conseil est bien sûr le bienvenu. Suite à cette fonction tableau_3, je fais de même pour tableau_4 , 5 et 6. Le code est identique sauf que lors de l'examen sur F je démarre à 14 et non plus à 13 pour tableau_4, idem je démarre à 15 pour tableau_5 ect. A partir de là, je voudrais ne faire qu'une seule fonction tableau_opt qui utilise varargin et un switch mais je me suis rendu que c'est laborieux. J'y suis parvenu en réalisant un switch sur la longueur du premier paramètre : Dreflux_123_liquide / Dreflux_1234_liquide / Dreflux_12345_liquide...mais j'ai rajouté un z à gazeux qui devient gazzeux afin que liquide, melange et gazzeux aient 7 lettres. Ainsi lors de l'examen sur F je ne distingue plus comme précédemment sur le numel. Bref je n'arrive pas à m'en sortir autrement. C'est un peu archaïque.

    Voici le code :

    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
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    function mat=tableau_opt(varargin)
     
    mat=[];
    if isempty(varargin{1} | varargin{2})
       return
    end
    F=inputname(1); 
    switch numel(inputname(1))
     
       case 19
     
    mat(:,1)=varargin{1}(:,1)';
    mat(:,2)=max(varargin{2}(:,2),varargin{2}(:,3));
     
    A=mat(:,1);
     
    B=mat(:,2);
    mat(:,3)=zeros(size(varargin{1},1),1);
    C=mat(:,3);
    for i=1:size(varargin{1},1)
        C(i)=max(varargin{3}(A(i):B(i)));
    end
    mat(:,3)=C;
     
    mat(:,4)=zeros(size(varargin{1},1),1);
    D=mat(:,4);
     
    for i=1:size(varargin{1},1);
        if (C(i)<=4)
            D(i)=1;
        elseif ((C(i)>4) & (C(i)<6.8))
            D(i)=2;
        else
            D(i)=3;
        end
    end
    mat(:,4)=D;
     
    mat(:,5)=zeros(size(varargin{1},1),1);
    E=mat(:,5); 
     
    for i=1:size(varargin{1},1);
     
            if (F(13:end)=='liquide')
            E(i)=1;
            elseif (F(13:end)=='melange')
            E(i)=2;
            elseif (F(13:end)=='gazzeux')
            E(i)=3;   
            end
    end
    mat(:,5)=E;
     
     
        case 20
     
            %tableau_4
     
    mat(:,1)=varargin{1}(:,1)';
    mat(:,2)=max(varargin{2}(:,2),varargin{2}(:,3));
     
    A=mat(:,1);
    B=mat(:,2);
    mat(:,3)=zeros(size(varargin{1},1),1);
    C=mat(:,3);
    for i=1:size(varargin{1},1)
        C(i)=max(varargin{3}(A(i):B(i)));
    end
    mat(:,3)=C;
     
    mat(:,4)=zeros(size(varargin{1},1),1);
    D=mat(:,4);
     
    for i=1:size(varargin{1},1);
        if (C(i)<=4)
            D(i)=1;
        elseif ((C(i)>4) & (C(i)<6.8))
            D(i)=2;
        else
            D(i)=3;
        end
    end
    mat(:,4)=D;
     
    mat(:,5)=zeros(size(varargin{1},1),1);
    E=mat(:,5);
     
    for i=1:size(varargin{1},1);
     
            if (F(14:end)=='liquide')
            E(i)=1;
            elseif (F(14:end)=='melange')
            E(i)=2;
            elseif (F(14:end)=='gazzeux')
            E(i)=3;     
            end
    end
    mat(:,5)=E;
     
     
        case 21
     
            %tableau_5
     
    mat(:,1)=varargin{1}(:,1)';
    mat(:,2)=max(varargin{2}(:,2),varargin{2}(:,3));
     
    A=mat(:,1);
    B=mat(:,2);
    mat(:,3)=zeros(size(varargin{1},1),1);
    C=mat(:,3);
    for i=1:size(varargin{1},1)
        C(i)=max(varargin{3}(A(i):B(i)));
    end
    mat(:,3)=C;
     
    mat(:,4)=zeros(size(varargin{1},1),1);
    D=mat(:,4);
     
    for i=1:size(varargin{1},1);
        if (C(i)<=4)
            D(i)=1;
        elseif ((C(i)>4) & (C(i)<6.8))
            D(i)=2;
        else
            D(i)=3;
        end
    end
    mat(:,4)=D;
     
    mat(:,5)=zeros(size(varargin{1},1),1);
    E=mat(:,5);
     
    for i=1:size(varargin{1},1);
     
            if (F(15:end)=='liquide')
            E(i)=1;
            elseif (F(15:end)=='melange')
            E(i)=2;
            elseif (F(15:end)=='gazzeux')
            E(i)=3;     
            end
    end
    mat(:,5)=E;
     
     
    case 22
     
            %tableau_6
     
    mat(:,1)=varargin{1}(:,1)';
    mat(:,2)=max(varargin{2}(:,2),varargin{2}(:,3));
     
    A=mat(:,1);
    B=mat(:,2);
    mat(:,3)=zeros(size(varargin{1},1),1);
    C=mat(:,3);
    for i=1:size(varargin{1},1)
        C(i)=max(varargin{3}(A(i):B(i)));
    end
    mat(:,3)=C;
     
    mat(:,4)=zeros(size(varargin{1},1),1);
    D=mat(:,4);
     
    for i=1:size(varargin{1},1);
        if (C(i)<=4)
            D(i)=1;
        elseif ((C(i)>4) & (C(i)<6.8))
            D(i)=2;
        else
            D(i)=3;
        end
    end
    mat(:,4)=D;
     
    mat(:,5)=zeros(size(varargin{1},1),1);
    E=mat(:,5);
     
    for i=1:size(varargin{1},1);
     
            if (F(16:end)=='liquide')
            E(i)=1;
            elseif (F(16:end)=='melange')
            E(i)=2;
            elseif (F(16:end)=='gazzeux')
            E(i)=3;     
            end
    end
    mat(:,5)=E;
     
     
    end

    Donc, Dut : vois-tu un moyen de contourner ce problème de rajout de z d'une part à gazzeux ? Si oui, comment ? Et d'autre part, comment pourrais-je simplifier ce dernier code pour le rendre aussi succinct que celui de hier avec ma fonction reflux ?

  6. #6
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Plutôt que d'utiliser le nom rentré dans la fonction, je verrai plutôt un autre paramètre passé à cette fonction ('liquide', 'melange', ou 'gazeux').
    Sinon un simple split selon le caractère '_' ferait l'affaire, et permettrait aussi de comparer correctement tes chaînes de caractères.

    Je te conseille aussi de donner des noms parlant à tes variables. Parce que là A, B, C, D, E..

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Code avec des dates
    Par Wackolas dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 16/02/2009, 09h04
  2. génération de code avec une boucle
    Par fandeDB dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 18/11/2007, 11h26
  3. optimiser mon code avec une boucle for?
    Par Invité dans le forum ActionScript 3
    Réponses: 1
    Dernier message: 16/11/2007, 08h33
  4. Réponses: 1
    Dernier message: 17/06/2007, 00h49
  5. [PHP-JS] Optimisation du code avec des boucles
    Par jiojioforever dans le forum Langage
    Réponses: 3
    Dernier message: 15/06/2007, 16h02

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