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 :

Fonction Find sur chaque ligne d'une matrice creuse


Sujet :

MATLAB

  1. #1
    Futur Membre du Club
    Inscrit en
    Janvier 2011
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 14
    Points : 6
    Points
    6
    Par défaut Fonction Find sur chaque ligne d'une matrice creuse
    Bonjour,

    Alors je vous explique le problème :

    J'ai une matrice creuse, et je voudrais récupérer sur chaque ligne les emplacements des éléments non-nuls, pour ensuite les concaténer.
    Pour l'instant j'ai fait ça avec une boucle for, sur chaque ligne de la matrice,
    en utilisant find, mais c'est assez lent. J'aimerais donc pouvoir me passer
    de cette boucle mais je ne vois pas comment. Une solution serait de faire
    un "find" sur toute la matrice et récupérer le vecteur résultant pour le
    découper ensuite, mais le nombre d'éléments à "découper" varie.

    Auriez-vous une idée pour se passer de cette satanée boucle ? ;-)

    Merci d'avance,

    Mathieu

  2. #2
    Expert éminent sénior
    Avatar de Caro-Line
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    9 458
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 9 458
    Points : 14 830
    Points
    14 830
    Par défaut
    Peut-être avec SPARSE ?
    Règles du Forum

    Adepte de la maïeutique

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2007
    Messages : 58
    Points : 69
    Points
    69
    Par défaut
    Essaie de remplacer le find par du "logical indexing"

    En gros faire c'est beaucoup plus long que de faire.

    Comme ça ça à l'air ridicule, mais la fonction find dans une boucle peut prendre un temps monstrueux.

  4. #4
    Futur Membre du Club
    Inscrit en
    Janvier 2011
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 14
    Points : 6
    Points
    6
    Par défaut
    En fait pour être plus clair voici le bout de code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    for i=1:size(Adj1)
     
            L=find(Adj1(i,: ));                          
            Lab=[Vlbl1(i) Vlbl1(L)];                   
            Str=strcat(num2str(sort(Lab(: ))));          
            NumLab=str2double(Str);                     
            LabMat1(i)=NumLab;                         
     
    end
    Adj1 étant une matrice creuse et Vlbl un vecteur. Je ne pourrais pas utiliser
    le "logical indexing" ici à la place de find, car ce dernier me retourne les
    emplacements des élements ~= 0, et pas les éléments eux-mêmes.

    Merci quand même pour les pistes ;-)

  5. #5
    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 : 52 882
    Points
    52 882
    Par défaut
    Je ferais comme ceci :

    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
    N = 3;
    X = sparse((rand(N)>.3).*randi(10,N));
     
    idx = find(X);
     
    nRows = size(X,1);
    nX = numel(X);
     
    V = cell(1,nRows);
     
    for n = 1:nRows
        idx2 = ismembc(idx,n:nRows:nX);
        if any(idx2)
            V{n} = X(idx(idx2));
        end
    end
    sinon je ne comprends pas bien à quoi servent les lignes suivantes de ton code :
    Citation Envoyé par Mathieu999 Voir le message

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
            Str=strcat(num2str(sort(Lab(: ))));          
            NumLab=str2double(Str);
    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)

  6. #6
    Futur Membre du Club
    Inscrit en
    Janvier 2011
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 14
    Points : 6
    Points
    6
    Par défaut
    Oula je ne comprends pas du tout ton code, Dut ;-)
    Va falloir que je décortique tout ça...

    Sinon pour les lignes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Str=strcat(num2str(sort(Lab(: ))));          
    NumLab=str2double(Str);
    En fait je transforme d'abord le vecteur Lab en strings, et puis
    je concatène ceux-ci. Je les retransforme ensuite en nombre pour pouvoir
    les manipuler plus facilement.

    Merci pour ta réponse en tout cas !

  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 : 52 882
    Points
    52 882
    Par défaut
    Citation Envoyé par Mathieu999 Voir le message
    Oula je ne comprends pas du tout ton code, Dut ;-)
    En fait j'utilise l'indexage linéaire :


    Sinon, ISMEMBC est un fichier MEX qui fonctionne comme la fonction ISMEMBER mais uniquement sur des vecteurs. Comme c'est un fichier MEX, le code est plus rapide qu'avec ISMEMBER (qui fait d'ailleurs appel à ISMEMBC)
    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
    Inscrit en
    Juin 2007
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2007
    Messages : 58
    Points : 69
    Points
    69
    Par défaut
    Et pourquoi ne pas utiliser ceci:

    J'utilise aussi de grande sparse matrices et généralement j'utilise cette commande.

    EDIT: Pas trop grande non plus.

  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 : 52 882
    Points
    52 882
    Par défaut
    Citation Envoyé par Buide Voir le message
    Dans ce cas, je pense qu'il serait plus efficace de faire :

    Sinon pour la question initiale, Mathieu999 voulait parcourir la matrice ligne par ligne...
    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
    Inscrit en
    Juin 2007
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2007
    Messages : 58
    Points : 69
    Points
    69
    Par défaut
    Citation Envoyé par Dut Voir le message
    Dans ce cas, je pense qu'il serait plus efficace de faire :

    Sinon pour la question initiale, Mathieu999 voulait parcourir la matrice ligne par ligne...
    Oui, tu as raison...
    Désolé d'avoir dévié du topic...

  11. #11
    Futur Membre du Club
    Inscrit en
    Janvier 2011
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 14
    Points : 6
    Points
    6
    Par défaut
    Enfin si vous avez des idées pour faire ça non pas ligne par ligne
    mais en une seule fois par opération matricielle je suis preneur
    aussi ;-)

  12. #12
    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 : 52 882
    Points
    52 882
    Par défaut
    Quel est le problème avec la fonction NONZEROS alors ?
    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)

  13. #13
    Futur Membre du Club
    Inscrit en
    Janvier 2011
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 14
    Points : 6
    Points
    6
    Par défaut
    Désolé pour la réponse tardive ;-)

    en fait la fonction non-zeros donne les valeurs des emplacements
    différents de 0, et moi j'ai besoin des endroits proprement dit où
    les éléments sont différents de 0.

  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 : 52 882
    Points
    52 882
    Par défaut
    Et donc quel est le problème avec FIND ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    >> N = 3;
    >> X = sparse((rand(N)>.3).*randi(10,N))
     
    X =
     
       (1,1)        5
       (2,1)        5
       (3,1)        7
       (2,2)        8
       (3,2)        3
       (1,3)        7
       (2,3)        7
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    >> full(X)
     
    ans =
     
         5     0     7
         5     8     7
         7     3     0
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >> idx = find(X)
     
    idx =
     
         1
         2
         3
         5
         6
         7
         8
    ou
    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
    >> [r,c] = find(X)
     
    r =
     
         1
         2
         3
         2
         3
         1
         2
     
     
    c =
     
         1
         1
         1
         2
         2
         3
         3
    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)

Discussions similaires

  1. Réponses: 2
    Dernier message: 21/10/2011, 21h04
  2. Réponses: 6
    Dernier message: 04/09/2011, 21h31
  3. Réponses: 3
    Dernier message: 08/04/2009, 12h10
  4. Réponses: 16
    Dernier message: 15/08/2008, 11h08
  5. [VBA]Exécuter une tache sur chaque ligne d'une table
    Par Tierisa dans le forum VBA Access
    Réponses: 1
    Dernier message: 13/04/2007, 16h53

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