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 :

Sélection d'un élément d'une matrice selon conditions déterminées par autres matrices


Sujet :

MATLAB

  1. #1
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Mars 2007
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2007
    Messages : 86
    Points : 62
    Points
    62
    Par défaut Sélection d'un élément d'une matrice selon conditions déterminées par autres matrices
    Bonjour, c'est encore moi...

    Pour faire simple voici mon problème que j'aimerai bien traduire en matlab (mais je trouve pas les fonctions adéquates) :

    Soit les données :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    A =
    1 8 7
    1 4 5
    4 5 7
    8 4 3
    1 7 9
     
    B =
    4 5 
    7 1
     
    C =
    8
    1
    J'aimerai bien que pour chaque ligne de B, je sélectionne les lignes de A qui contiennent les 2 éléments de la ligne de A (peu importe l'ordre). Et que dans cette sélection je ne garde que l'élément (le troisième si on retire les éléments de la ligne de B) qui ne figure pas dans C.

    Donc avoir en sortie le tableau D :
    7
    9

    Je ne sais pas si je me suis exprimé assez clairement mais si vous aviez une idée de comment faire ca m'aiderait vraiment beaucoup !

    Bon we de Paques !

  2. #2
    Membre régulier
    Femme Profil pro
    Inscrit en
    Mars 2007
    Messages
    130
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mars 2007
    Messages : 130
    Points : 93
    Points
    93
    Par défaut
    salut !

    Je pense que la fonction "find" de matlab peut t'aider. Elle permet de trouver des valeurs dans une matrice... cf 'help find'

    Bon courage !

  3. #3
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Mars 2007
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2007
    Messages : 86
    Points : 62
    Points
    62
    Par défaut
    Oui j'avais pensé à cela aussi mais je me posais la question s'il n'existait pas de fonction "contain" ou quelque chose dans le genre afin de voir si les éléments d'une matrice sont présents dans une autre...

    Je cherche mais je trouve rien...

  4. #4
    Membre régulier
    Femme Profil pro
    Inscrit en
    Mars 2007
    Messages
    130
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mars 2007
    Messages : 130
    Points : 93
    Points
    93
    Par défaut
    Bin.. pour moi find est une bonne solution ça te permet de voir si un élément est présent dans une matrice donc après il suffit de se creuser un peu les méninges pour faire ton algorithme mais ça m'a l'air faisable avec cette fonction.

    Par contre méfie-toi parce que find te ressortira les indices de ta matrice mise en vecteur il me semble.

  5. #5
    Membre éprouvé
    Avatar de rostomus
    Homme Profil pro
    Doctorant électronique et traitement du signal
    Inscrit en
    Décembre 2006
    Messages
    791
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant électronique et traitement du signal

    Informations forums :
    Inscription : Décembre 2006
    Messages : 791
    Points : 1 205
    Points
    1 205
    Par défaut
    Bonjour,

    Je pense que la fonction que tu cherche est ismember (voir le help), combine la avec la fonction all.

    Bon courage
    MATLAB 7.4 (R2007a) WIN XP SP2
    -------------------------------------

  6. #6
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Mars 2007
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2007
    Messages : 86
    Points : 62
    Points
    62
    Par défaut
    Bonjour,

    J'ai un peu regardé les fonctions que vous m'avez indiquées et c'est bien les fonctions que je devrai utiliser...

    Seulement j'arrive pas à faire en sorte qu'il y ait prise en compte de toute la ligne de B et pas seulement d'un seul élément...
    De plus, je vois pas trop la différence entre la fonction all et any...

    Voici le code qui marche pour la premiere ligne de B (j'ai l'impression qu'il prend l'ordre en compte)...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    A = [1 8 7 ; 1 4 5; 4 5 7; 8 4 3; 1 7 9]
    B = [4 5 ; 7 1]
    C = [8; 1]
     
    A(all(ismember(A,B),2),:)

  7. #7
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 53 160
    Points
    53 160
    Par défaut
    Ceci devrait faire l'affaire:
    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
    A = [1 8 7 ; 1 4 5; 4 5 7; 8 4 3; 1 7 9]
    B = [4 5 ; 7 1]
    C = [8 ; 1]
     
    [m,n]=size(A);
     
    % On cherche les paires exactes de colonnes de A et de B (triées)
    idx=ismember(sort([A(:,[1 2]);A(:,[1 3]);A(:,[2 3])],2),sort(B,2),'rows');
    idx=find(idx); % idx est compris entre 1 et 3*size(A,1)
     
    % On transforme idx pour retrouver des indices entre 1 et size(A,1)
    r=idx-m*floor(idx/m);
    r=r+m*(r==0);
     
    % On détermine à quelle colonne appartenait la troisième valeur (pas dans B)
    % On utilise le rangement [A(:,[1 2]);A(:,[1 3]);A(:,[2 3])]
    c=(idx<=m)+(idx<=2*m)+(idx<=3*m);
     
    % On transforme r et c en indices linéraires
    idx=sub2ind([m n],r,c);
     
    % On sépare les valeurs qui ne doivent pas être dans C
    D=setdiff(A(idx),C(:))
    Il faudra peut-être que je prennes plus de temps pour expliquer ce code.
    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

  8. #8
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Mars 2007
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2007
    Messages : 86
    Points : 62
    Points
    62
    Par défaut
    Eh ben ! Chapeau! J'aurais jamais pensé à cela...

    Il y a juste un petit détail à régler : en fait, la matrice D s'affiche par ordre croissant mais j'aimerai bien que les valeurs s'affichent pour chaque ligne de B --> donc pour les 2 valeurs de la ligne de B, c'est cet élément qui se trouve dans la matrice A (et qu'on ne retrouve pas dans la matrice C).

    Mais sinon je vous remercie vraiment ! Ca m'aide beaucoup !

  9. #9
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 53 160
    Points
    53 160
    Par défaut
    Citation Envoyé par bernard6
    j'aimerai bien que les valeurs s'affichent pour chaque ligne de B
    Il suffit d'utiliser une boucle FOR-END et de boucler sur le nombre de lignes de B en utilisant à chaque fois B(i, soit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    idx=ismember(sort([A(:,[1 2]);A(:,[1 3]);A(:,[2 3])],2),sort(B(i,:),2),'rows');
    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

  10. #10
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Mars 2007
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2007
    Messages : 86
    Points : 62
    Points
    62
    Par défaut
    Bonjour,

    J'ai bien saisi votre raisonnement mais j'ai jamais vraiment compris les boucles en Matlab... Chaque fois que j'utilise des boucles, il ne me conserve que la dernière itération ... Je suppose qu'il faut faire une sorte de tableau qui conserverait les résultats de toutes les itérations mais je n'y suis jamais parvenu en Matlab...

    En appliquant ce que vous m'avez dit, j'ai modifié le code de la façon suivante :

    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
    A = [1 8 7 ; 1 4 5; 4 5 7; 8 4 3; 1 7 9]
    B = [7 1 ; 4 5]
    C = [8 ; 1]
     
    [m,n]=size(A);
    [p q]=size(B);
    % On cherche les pairs exactes de couple de colonnes de A et de B (lignes triées par ordre croissant)
     
    for i=1:p,
    idx=ismember(sort([A(:,[1 2]);A(:,[1 3]);A(:,[2 3])],2),sort(B(i,:),2),'rows');
    % idx=ismember(sort([A(:,[1 2]);A(:,[1 3]);A(:,[2 3])],2),sort(B,2),'rows') % on decompose A de deux éléments en deux éléments (par ordre croissant) et on le compare avec B classé par ordre croissant de lignes
    idx=find(idx) % idx est compris entre 1 et 3*size(A,1), idx correspond maintenant aux nums de lignes qui présentent la valeur 1 ci-dessus (donc A et B correspondent)
    end
     
    % On transforme idx pour retrouver les indices entre 1 et size(A,1)
    r=idx-m*floor(idx/m)
    r=r+m*(r==0)% là où r est égal à 0 on remplace par le nombre de lignes de A
     
    % On détermine à quelle colonne appartenait la troisième valeur (pas dans B)
    % On utilise le rangement [A(:,[1 2]);A(:,[1 3]);A(:,[2 3])]
    c=(idx<=m)+(idx<=2*m)+(idx<=3*m);
     
    % On transforme r et c en indices linéraires
    idx=sub2ind([m n],r,c)
     
    % On sépare les valeurs qui ne doivent pas être dans C
    D=setdiff(A(idx),C(:))
    NB : j'ai changé la matrice B pour voir si ca tient compte de l'ordre...

    Je vous remercie pour le temps que vous consacrez à m'aider.

  11. #11
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 53 160
    Points
    53 160
    Par défaut
    En fait, je pensais englober tout le bloc de fonctions dans la boucle FOR-END :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for i=1:p
       idx=ismember(sort([A(:,[1 2]);A(:,[1 3]);A(:,[2 3])],2),sort(B(i,:),2),'rows');
       ...
       D=setdiff(A(idx),C(:));
    end
    Pour conserver chaque valeur, il faut procéder comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    D=[];
    for n=1:10
       D=[D n];
    end
    D
    Voir la concaténation de matrice dans la documentation.
    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

  12. #12
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Mars 2007
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2007
    Messages : 86
    Points : 62
    Points
    62
    Par défaut
    C'est parfait ! Je viens enfin de comprendre !

    Merci bcp !

    (pas mal les Easter Eggs )

  13. #13
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Mars 2007
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2007
    Messages : 86
    Points : 62
    Points
    62
    Par défaut
    Bonjour, après avoir adapté le script ci dessus à mes données, j'ai rencontré une série de problèmes dus au caractère différent de ces données.

    J'ai envisagé plusieurs solutions pour les problèmes rencontrés mais je n'arrive pas à les mettre en oeuvre...

    Voici les problèmes :


    • si pas d'élément intégré dans D selon une ligne de B, il faut en tenir compte
    • il ne faut pas qu'il y ait deux éléments intégrés par ligne de B (il n'en faut qu'un!)
    • il ne faut pas que plusieurs éléments de D soient semblables



    Ces problèmes sont mieux détaillés dans le code ci-dessous :

    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
     
    Points = csvread('points artificiels.txt');
     
    A = [85 70 90; 30 85 70; 30 70 90; 120 85 90; 55 30 90;110 80 90; 40 55 30; 40 55 90; 75 110 90; 75 40 90]
    B = [90 55; 55 70; 70 90]
    C = [90 ; 55; 70]
     
    [m,n]=size(A);
    [p q]=size(B);
    % On cherche les pairs exactes de couple de colonnes de A et de B (lignes triées par ordre croissant)
    D = [];
    for i=1:p,
    idx=ismember(sort([A(:,[1 2]);A(:,[1 3]);A(:,[2 3])],2),sort(B(i,:),2),'rows');
    % idx=ismember(sort([A(:,[1 2]);A(:,[1 3]);A(:,[2 3])],2),sort(B,2),'rows') % on decompose A de deux éléments en deux éléments (par ordre croissant) et on le compare avec B classé par ordre croissant de lignes
    idx=find(idx); % idx est compris entre 1 et 3*size(A,1), idx correspond maintenant aux nums de lignes qui présentent la valeur 1 ci-dessus (donc A et B correspondent)
     
     
    % On transforme idx pour retrouver les indices entre 1 et size(A,1)
    r=idx-m*floor(idx/m);
    r=r+m*(r==0); % là où r est égal à 0 on remplace par le nombre de lignes de A
     
    % On détermine à quelle colonne appartenait la troisième valeur (pas dans B)
    % On utilise le rangement [A(:,[1 2]);A(:,[1 3]);A(:,[2 3])]
    c=(idx<=m)+(idx<=2*m)+(idx<=3*m);
     
    % On transforme r et c en indices linéraires
    idx=sub2ind([m n],r,c);
     
    % On sépare les valeurs qui ne doivent pas être dans C et on conserve
    % toutes les valeurs des itérations !
    D = [D; setdiff(A(idx),C(:))];
     
        % PROBLEME 1 : si pas d'élément intégré par ligne de B, on met comme code 000 pour
        % pouvoir spécifier après qu'on ne doit pas prendre en compte cet élément
        if ??? % j'arrive pas à traduire cette condition
            D(i,1) == 000
        end
     
        
        % PROBLEME 2 : si deux éléments intégrés par ligne de B (le nombre max de points intégrés ne peut être que 2), on ne garde que l'élément qui
        % figure le plus près du Segment (je fais simplement la moyenne des
        % distances du points aux deux extrémités du segment!)
        if ??? % j'arrive pas à traduire cette condition
           
            % indice1 et indice2 correspondent aux indices des points
            % semblables dans la matrice D (il faudrait un truc pour les
            % retrouver) --> normalement indice2 = indice1 + 1 (on peut garder
            % cela vu qu'on supprimera un des deux DONC la concordance des
            % lignes entre B et D sera conservée !
                    
            % calcul des 2 distances
            Dist1a = sqrt((Points(D(indice1,1),1)-Points(B(indice1,1),1))^2+(Points(D(indice1,2),1)-Points(B(indice1,1),2))^2+(Points(D(indice1,3),3)-Points(B(indice1,1),3))^2)
            Dist1b = sqrt((Points(D(indice1,1),1)-Points(B(indice1,2),1))^2+(Points(D(indice1,2),1)-Points(B(indice1,2),2))^2+(Points(D(indice1,3),3)-Points(B(indice1,2),3))^2)
            Dist1 = (Dist1a + Dist1b)/2
            
            Dist2a = sqrt((Points(D(indice2,1),1)-Points(B(indice2,1),1))^2+(Points(D(indice2,2),1)-Points(B(indice2,1),2))^2+(Points(D(indice2,3),3)-Points(B(indice2,1),3))^2)
            Dist2b = sqrt((Points(D(indice2,1),1)-Points(B(indice2,2),1))^2+(Points(D(indice2,2),1)-Points(B(indice2,2),2))^2+(Points(D(indice2,3),3)-Points(B(indice2,2),3))^2)
            Dist2 = (Dist2a + Dist2b)/2
            
            % on élimine dans D l'élément qui présente la plus grande distance
            if Dist1 > Dist2,
                delete(D(indice1,1))
            end
     
        end
                
    end
    D
        
     
    % PROBLEME 3 : si plusieurs éléments de D sont semblables, on ne conserve que le point le
    % plus proche du segment et on attribue le code 000 à l'autre.
     
    if ???
      %  il faut trouver un moyen pour identifier les indices des points
      %  semblables, une fois cette étape franchie il faudra simplement faire
      %  comme pour le problème 2
      
      % ensuite on sélectionne l'indice qui se réfère à le plus petite distance
      % et on garde celui là alors qu'on attribue le code 000 aux autres
      % points.
     
     
    end
    En pièce jointe figure mon fichier de points qui est lu au début du programme...

    Si vous voyez comment faire, ca m'aiderait beaucoup parce que ce sont des opérations que je ne maîtrise pas du tout étant débutant...

    Un grand merci d'avance pour votre aide !
    Fichiers attachés Fichiers attachés

  14. #14
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 53 160
    Points
    53 160
    Par défaut
    Pour les deux premiers problème, je ferais quelque chose comme ça :
    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
    sA=sort([A(:,[1 2]);A(:,[1 3]);A(:,[2 3])],2);
    for i=1:p,
    idx=ismember(sA,sort(B(i,:),2),'rows');
    % idx=ismember(sort([A(:,[1 2]);A(:,[1 3]);A(:,[2 3])],2),sort(B,2),'rows') % on decompose A de deux éléments en deux éléments (par ordre croissant) et on le compare avec B classé par ordre croissant de lignes
    idx=find(idx); % idx est compris entre 1 et 3*size(A,1), idx correspond maintenant aux nums de lignes qui présentent la valeur 1 ci-dessus (donc A et B correspondent)
     
     
    % On transforme idx pour retrouver les indices entre 1 et size(A,1)
    r=idx-m*floor(idx/m);
    r=r+m*(r==0); % là où r est égal à 0 on remplace par le nombre de lignes de A
     
    % On détermine à quelle colonne appartenait la troisième valeur (pas dans B)
    % On utilise le rangement [A(:,[1 2]);A(:,[1 3]);A(:,[2 3])]
    c=(idx<=m)+(idx<=2*m)+(idx<=3*m);
     
    % On transforme r et c en indices linéraires
    idx=sub2ind([m n],r,c);
     
    % On sépare les valeurs qui ne doivent pas être dans C et on conserve
    % toutes les valeurs des itérations !
     
    tempD=setdiff(A(idx),C(:));
     
     
        % PROBLEME 1 : si pas d'élément intégré par ligne de B, on met comme code 000 pour
        % pouvoir spécifier après qu'on ne doit pas prendre en compte cet élément
        if isempty(tempD) % j'arrive pas à traduire cette condition
            D = [D; 0];
     
        % PROBLEME 2 : si deux éléments intégrés par ligne de B (le nombre max de points intégrés ne peut être que 2), on ne garde que l'élément qui
        % figure le plus près du Segment (je fais simplement la moyenne des
        % distances du points aux deux extrémités du segment!)
        elseif numel(tempD)>1 % j'arrive pas à traduire cette condition
     
            % indice1 et indice2 correspondent aux indices des points
            % semblables dans la matrice D (il faudrait un truc pour les
            % retrouver) --> normalement indice2 = indice1 + 1 (on peut garder
            % cela vu qu'on supprimera un des deux DONC la concordance des
            % lignes entre B et D sera conservée !
     
            % calcul des 2 distances
            Dist1=...
            Dist2=...
            % on élimine dans D l'élément qui présente la plus grande distance
            if Dist1 > Dist2,
                tempD(???)=[]
            end
     
            D = [D; tempD];
        end
     
    end
    Voici un truc pour le 3ème problème:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    D=[1 2 3 4 3 4 5 6 2 2]
    uniqD=unique(D)
    nD=histc(D,uniqD)
    [uniqD(:) nD(:)]
    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

  15. #15
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Mars 2007
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2007
    Messages : 86
    Points : 62
    Points
    62
    Par défaut
    Ca marche !

    Enfin il ne me reste plus que le 3eme problème, mais ça devrait être vite résolu !

    Le problème résolu je mettrai le code si qqu avait un problème semblable...

    Merci beaucoup !!!

  16. #16
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Mars 2007
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2007
    Messages : 86
    Points : 62
    Points
    62
    Par défaut
    Bonjour,

    Voilà j'ai le code qui marche... (enfin pour mes données)

    Je vous le mets ici si vous aviez un problème semblable

    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
     
    Points = csvread('points artificiels.txt');
     
    A = [85 70 90; 30 85 70; 30 70 90; 120 85 90; 55 30 90;110 80 90; 40 55 30; 40 55 90; 75 110 90; 75 40 90]
    B = [90 55; 55 70; 70 85; 85 90]
    C = [90 ; 55; 70]
     
    [m,n]=size(A);
    [p q]=size(B);
    % On cherche les pairs exactes de couple de colonnes de A et de B (lignes triées par ordre croissant)
    D = [];
    sA=sort([A(:,[1 2]);A(:,[1 3]);A(:,[2 3])],2);
    for i=1:p,
    idx=ismember(sA,sort(B(i,:),2),'rows');
    % idx=ismember(sort([A(:,[1 2]);A(:,[1 3]);A(:,[2 3])],2),sort(B,2),'rows') % on decompose A de deux éléments en deux éléments (par ordre croissant) et on le compare avec B classé par ordre croissant de lignes
    idx=find(idx); % idx est compris entre 1 et 3*size(A,1), idx correspond maintenant aux nums de lignes qui présentent la valeur 1 ci-dessus (donc A et B correspondent)
     
     
    % On transforme idx pour retrouver les indices entre 1 et size(A,1)
    r=idx-m*floor(idx/m);
    r=r+m*(r==0); % là où r est égal à 0 on remplace par le nombre de lignes de A
     
    % On détermine à quelle colonne appartenait la troisième valeur (pas dans B)
    % On utilise le rangement [A(:,[1 2]);A(:,[1 3]);A(:,[2 3])]
    c=(idx<=m)+(idx<=2*m)+(idx<=3*m);
     
    % On transforme r et c en indices linéraires
    idx=sub2ind([m n],r,c);
     
    % On sépare les valeurs qui ne doivent pas être dans C et on conserve
    % toutes les valeurs des itérations !
    tempD = setdiff(A(idx),C(:))
     
     
     
     
        % PROBLEME 1 : si pas d'élément intégré par ligne de B, on met comme code 0 pour
        % pouvoir spécifier après qu'on ne doit pas prendre en compte cet élément
        if isempty(tempD) % j'arrive pas à traduire cette condition
            D = [D; 0];
            % OK -> PROB résolu !
     
        % PROBLEME 2 : si deux éléments intégrés par ligne de B (le nombre max de points intégrés ne peut être que 2), on ne garde que l'élément qui
        % figure le plus près du Segment (je fais simplement la moyenne des
        % distances du points aux deux extrémités du segment!)
        elseif numel(tempD)>1 % j'arrive pas à traduire cette condition
            indice1 = tempD (1,1);
            indice2 = tempD (2,1);
     
            % remplacer tous les D par tempD
     
            % indice1 et indice2 correspondent aux indices des points
            % semblables dans la matrice D (il faudrait un truc pour les
            % retrouver) --> normalement indice2 = indice1 + 1 (on peut garder
            % cela vu qu'on supprimera un des deux DONC la concordance des
            % lignes entre B et D sera conservée !
     
            % calcul des 2 distances
            %Prob pour B --> il faut retrouver son indice  --> i ???
            Dist1a = sqrt((Points(indice1,1)-Points(B(i,1),1))^2+(Points(indice1,2)-Points(B(i,1),2))^2+(Points(indice1,3)-Points(B(i,1),3))^2);
            Dist1b = sqrt((Points(indice1,1)-Points(B(i,1),1))^2+(Points(indice1,2)-Points(B(i,1),2))^2+(Points(indice1,3)-Points(B(i,1),3))^2);
            Dist1 = (Dist1a + Dist1b)/2;
     
            Dist2a = sqrt((Points(indice2,1)-Points(B(i,1),1))^2+(Points(indice2,2)-Points(B(i,1),2))^2+(Points(indice2,3)-Points(B(i,1),3))^2);
            Dist2b = sqrt((Points(indice2,1)-Points(B(i,1),1))^2+(Points(indice2,2)-Points(B(i,1),2))^2+(Points(indice2,3)-Points(B(i,1),3))^2);
            Dist2 = (Dist2a + Dist2b)/2;
            % on élimine dans D l'élément qui présente la plus grande distance
            if Dist1 > Dist2,
                tempD = tempD (2,1)
            else
            %if Dist2 > Dist1,
                tempD = tempD (1,1)
            end
            % end  
       end
       D = [D; tempD]
    end
     
     
    % % PROBLEME 3 : si plusieurs éléments de D sont semblables, on ne conserve que le point le
    % % plus proche du segment et on attribue le code 0 à l'autre.
     
    % je crée une table valeur - fréquence d'apparition et je ferai des tests
    % de distance selon que fréquence =  2, 3 (je suppose qu'il n'est pas
    % possible qu'il y en ait +)
    uniqD=unique(D)
    nD=histc(D,uniqD)
    TabD = [uniqD(:) nD(:)]
     
     
    %  SI 2 OCCURRENCES
     
    nD2 = find (nD ==2)
    nD2Tab = TabD(nD2,1)
     
    % il faut connaître les deux points du segment voisin à partir desquels on
    % fait les mesures de distance --> on doit donc retrouver la ligne dans D
    % où figure la valeur (nD1Tab) et on aura les points voisins en prenant les
    % points correspondant de B
     
    nD2TabTest = ismember(D,nD2Tab)
    Tamp2 = nD2TabTest*1; % car plus loin on aimerait changer la matrice logique mais on peut pas directement
    [dd ddd] = size (D)
     
    for i=1:dd,
        if D(i,1) == 0,
            Tamp2 (i,1) = 9999  % de cette façon on est certain que il considere tjs le passage d'une ligne mais que cette valeur ne sera jamais prise dans les conditions ci-dessous
        end
    end
     
    Indice2Tab = find (Tamp2 == 1)
     
    D2 = D([Indice2Tab],:)
    Coord2PtsVoisins = B([Indice2Tab],:)
     
    % les lignes de D1 correspondent à celles de Coord2PtsVoisins
     
    % on fait maintenant le test pour les distances
    TabDist2a = ((Points([Coord2PtsVoisins(:,1)],1)-Points([D2],1)).^2+(Points([Coord2PtsVoisins(:,1)],2)-Points([D2],2)).^2+(Points([Coord2PtsVoisins(:,1)],3)-Points([D2],3)).^2).^(1/2);
    TabDist2b = ((Points([Coord2PtsVoisins(:,2)],1)-Points([D2],1)).^2+(Points([Coord2PtsVoisins(:,2)],2)-Points([D2],2)).^2+(Points([Coord2PtsVoisins(:,2)],3)-Points([D2],3)).^2).^(1/2);
    TabDist2 = (TabDist2a + TabDist2b)/2
    MinTabDist2 = min(TabDist2)
     
    %   % on sélectionne l'indice qui se réfère à le plus petite distance
    %   % et on garde celui là alors qu'on attribue le code 0 aux autres
    %   % points.
     
    xxx2 = find (Tamp2 == 1)
    indices = xxx2((find (TabDist2 == MinTabDist2))',1)
    D ((indices)',1) = 0
     
     
     
    % SI 3 OCCURRENCES
     
    nD3 = find (nD ==3)
    nD3Tab = TabD(nD3,1)
     
    % il faut connaître les deux points du segment voisin à partir desquels on
    % fait les mesures de distance --> on doit donc retrouver la ligne dans D
    % où figure la valeur (nD1Tab) et on aura les points voisins en prenant les
    % points correspondant de B
     
    nD3TabTest = ismember(D,nD3Tab)
    Tamp3 = nD3TabTest*1; % car plus loin on aimerait changer la matrice logique mais on peut pas directement
    [dd ddd] = size (D)
     
    for i=1:dd,
        if D(i,1) == 0,
            Tamp3 (i,1) = 9999  % de cette façon on est certain que il considere tjs le passage d'une ligne mais que cette valeur ne sera jamais prise dans les conditions ci-dessous
        end
    end
     
    Indice3Tab = find (Tamp3 == 1)
     
    D3 = D([Indice3Tab],:)
    Coord3PtsVoisins = B([Indice3Tab],:)
     
    % les lignes de D3 correspondent à celles de Coord1PtsVoisins
     
    % pour envisager tous les cas, je décide de rajouter 2 lignes artificielles
    % (faudra supprimer)
     
    % on fait maintenant le test pour les distances
    TabDist3a = ((Points([Coord3PtsVoisins(:,1)],1)-Points([D3],1)).^2+(Points([Coord3PtsVoisins(:,1)],2)-Points([D3],2)).^2+(Points([Coord3PtsVoisins(:,1)],3)-Points([D3],3)).^2).^(1/2);
    TabDist3b = ((Points([Coord3PtsVoisins(:,2)],1)-Points([D3],1)).^2+(Points([Coord3PtsVoisins(:,2)],2)-Points([D3],2)).^2+(Points([Coord3PtsVoisins(:,2)],3)-Points([D3],3)).^2).^(1/2);
    TabDist3 = (TabDist3a + TabDist3b)/2
    MinTabDist3 = min(TabDist3)
     
    %   % on sélectionne l'indice qui se réfère à le plus petite distance
    %   % et on garde celui là alors qu'on attribue le code 0 aux autres
    %   % points.
     
    xxx3 = find (Tamp3 == 1)
    indices = xxx3((find (TabDist3 == MinTabDist3))',1)
    D ((indices)',1) = 0
    Merci pour ton aide DutMatlab !

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 06/06/2011, 13h56
  2. Réponses: 3
    Dernier message: 19/10/2006, 10h51
  3. Réponses: 4
    Dernier message: 09/08/2006, 12h05
  4. [VBA] sélection d'un élément dans une liste
    Par menguygw dans le forum Access
    Réponses: 3
    Dernier message: 26/04/2006, 13h18
  5. Sélection d'un élément dans une combobox
    Par cluis dans le forum IHM
    Réponses: 2
    Dernier message: 17/03/2006, 15h23

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