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 :

Détection spécifique sur un vecteur [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 Détection spécifique sur un vecteur
    Bonjour,

    J'ai un problème à résoudre et je souhaiterais avoir votre aide sur le sujet. Disons par exemple que j'ai un vecteur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    V=
    1618
    1619
    1620
    1645
    1653
    Je dois détecter dedans des événements. Un événement est caractérisé par des points consécutifs ou des points isolés. Par exemple ici, le segment [1618 1619 1620] et les points isolés [1645] et [1653] constituent des événements. J'ai besoin de détecter ces événements mais aussi leur durée. Par exemple, ici le premier événement dure 3 secondes et les deux autres 1 seconde chacun.

    Voilà, mais je ne sais pas trop comment faire : j'ai entendu parler de la fonction diff qui permettrait de faire la différences entre deux points et qui me permettrait ainsi de détecter un événement si la différence est >1 ou si elle vaut 0 (1653 - 1653=0 par exemple) mais pour la durée je ne sais pas.

  2. #2
    Membre averti
    Femme Profil pro
    Ingénieur informatique scientifique
    Inscrit en
    Mai 2010
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur informatique scientifique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2010
    Messages : 313
    Points : 301
    Points
    301
    Par défaut
    Bonjour,
    je me complique peut-être la vie mais voilà une solution qui fonctionne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    nbEvents = 1;
    dureesEvents = ones(1,length(V));
     
    for i = 2:length(V)
        if(V(i)== V(i-1)+1)
            dureesEvents(nbEvents) = dureesEvents(nbEvents)+1;
        else
            nbEvents = nbEvents + 1;
        end
    end
    dureesEvents = dureesEvents(1:nbEvents);
    Avec ton exemple ça donnerait:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    nbEvents = 3
    dureesEvents = [3,1,1]

  3. #3
    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
    Merci beaucoup mokochan, cela semble vraiment bien marcher ! Je te remercie. Je n'aurais jamais pensé que cela pourrait s'écrire ainsi. A présent je cherche un moyen de stocker d'une certaine façon les différents événements trouvés. Par exemple en reprenant mon exemple précédent, les événements sont :

    [1618 1619 1620] d'une durée de 3 secondes.

    [1645] d'une durée d'1 seconde.

    [1653] d'une durée d'1 seconde.

    L'idée c'est que je voudrais stocker d'une manière ou d'une autre ces différentes valeurs dans une matrice par exemple ou un tableau, du style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    resultat=
     
    evenement 1618 1619 1620 duree 3 sec
    evenement 1645                duree 1 sec
    evenement 1653                duree 1 sec

    Ce serait donc plutôt une matrice où chaque case représenterait un élément : chaque ligne serait constitué de la même façon : la chaîne de caractère "evenement" suivie par les nombres de l'événement en question, dans l'ordre et dans une case de la matrice comme ci-dessus, puis la chaîne "duree", puis le nombre qui représente la durée de l'événement et enfin la chaîne "sec". Bon, j'imagine que cela semble compliqué mais je voudrais donc que la matrice resultat soit ainsi générée automatiquement. En fait, ce serait tout aussi bien d'avoir cet ensemble resultat dans un fichier .txt

    EDIT

    Bon c'est sans doute un peu compliqué...ce que je voudrais, au moins, c'est récupérer les différents événements d'une façon ou d'une autre avec une séparation entre eux : 1618 1619 1620 | 1645 | 1653 mais là aussi je bute car je ne vois pas bien comment conserver les valeurs.

  4. #4
    Membre averti
    Femme Profil pro
    Ingénieur informatique scientifique
    Inscrit en
    Mai 2010
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur informatique scientifique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2010
    Messages : 313
    Points : 301
    Points
    301
    Par défaut
    Non c'est tout à fait faisable:

    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
     
    somme = 1;
    fid=fopen('fichierResultats.txt','w');
    if(fid>2)
        for j = 1:nbEvents
            valeurs = mat2str(V(somme:somme+dureesEvents(j)-1));
     
            valeurs=strrep(valeurs,'[','');                      
            valeurs=strrep(valeurs,']','');
            valeurs=strrep(valeurs,';',' ');
     
            somme = somme + dureesEvents(j); 
     
            fprintf(fid,'evenement %s duree %d sec\n',valeurs,dureesEvents(j));
        end
        fclose(fid);
    else
        disp('Impossible d''ouvrir le fichier!');
    end
    Ici j'écris directement les résultats dans un fichier. J'ouvre le fichier avec fopen, puis je fais une boucle sur chaque évenèment:
    - Je récupère les valeurs de V de cet évenèment et les met sous forme de chaîne avec mat2str,
    - Je transforme cette chaîne car elle est au format "[123;456;789]" donc je me sers de strrep pour retirer les "[" et "]" et remplacer les points-virgules par des espaces,
    - je met à jour la variable somme qui me sert à récupérer les bonnes valeurs de V à chaque fois,
    j'écris la ligne de résultats dans le fichier avec fprintf.

  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
    Merci mokochan, franchement je te tire mon chapeau car je pense qu'avec mes connaissances je n'aurais jamais trouvé cela tout seul, c'est tout simplement parfait.

    Je vais encore te solliciter une dernière fois pour une raison technique d'utilisation de ce script. En fait j'ai plus en tête de l'utiliser comme une 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
    function y=detection_ev(V)
    nbEvents = 1;
    dureesEvents = ones(1,length(V));
     
    %Detection des événements
     
    for i = 2:length(V)
        if(V(i)== V(i-1)+1)
            dureesEvents(nbEvents) = dureesEvents(nbEvents)+1;
        else
            nbEvents = nbEvents + 1;
        end
    end
    nbEvents;
    dureesEvents = dureesEvents(1:nbEvents);
     
    %Ecriture dans un fichier texte des résultats
     
    somme = 1;
    fid=fopen('fichierResultats.txt','w');
    if(fid>2)
        for j = 1:nbEvents
            valeurs = mat2str(V(somme:somme+dureesEvents(j)-1));
     
            valeurs=strrep(valeurs,'[','');                      
            valeurs=strrep(valeurs,']','');
            valeurs=strrep(valeurs,';',' ');
     
            somme = somme + dureesEvents(j); 
     
            fprintf(fid,'evenement %s duree %d sec\n',valeurs,dureesEvents(j));
        end
        fclose(fid);
    else
        disp('Impossible d''ouvrir le fichier!');
    end
    Et, ainsi je l’appellerai sur un certain vecteur dans un autre script :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    detection_ev(valeurs_Imp1_gazeux(:,1));
    Le problème c'est si je fais cela, avec le code ci-dessus, je vais certes avoir le fichier txt bien crée. Mais en fait j'aurais besoin, à chaque fois que j'utilise cette fonction dection_ev que la variable nbEvents et dureesEvents soit stockée en mémoire, c'est-à-dire qu'elles existent dans le "Workspace". J'ai un peu de mal avec les fonctions en fait : quand je lance le script nbEvents et dureeEvents n'apparaissent nul part dans le Workspace. Je cherche donc un moyen de les récupérer quelque soit le vecteurs. Cela aurait été bien si quelque chose comme detection_ev(V).nbEvents fonctionnait comme cela je stockerai ce nombre dans une autre variable mais cela ne marche pas.

    De la même manière j'aurais besoin qu'un fichier txt soit crée à chaque fois et qu'il porte le nom du vecteur passé en paramètre, par exemple detection_ev(V) devra me créer le fichier resultat_V.txt.

  6. #6
    Membre averti
    Femme Profil pro
    Ingénieur informatique scientifique
    Inscrit en
    Mai 2010
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur informatique scientifique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2010
    Messages : 313
    Points : 301
    Points
    301
    Par défaut
    Pas de quoi, à vrai dire je n'utilise que des fonctions très simples de Matlab! Je pense que tu devrais prendre le temps de lire quelques tutoriels sur Matlab, il y en a déjà un certain nombre ici: http://matlab.developpez.com/tutoriels/

    Mais bon aujourd'hui j'ai le temps alors je vais t'aider ^^
    Dans ta fonction je ne sais pas ce que c'est ce paramètre de retour "y", mais en tout cas si tu veux récupérer les variables nbEvents et dureeEvents et bien il suffit que ta fonction les renvoie!
    Sinon peut-être que le plus simple pour obtenir le nom de fichier est de directement le donner en paramètre d'entrée. Ta déclaration de fonction deviendrait:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [nbEvents,dureesEvents] = function detection_ev(valeurs,nomFichier)
    Du coup tu n'as plus qu'à changer l'instruction d'ouverture du fichier par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fid=fopen(nomFichier,'w');
    Comme ça quand tu appelles ta fonction, par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [events,durees] = function detection_ev(V,'resultats_V.txt')
    Tu verras les variables events et durees dans ton workspace (normalement) et le fichier créé aura bien le nom que tu veux.

  7. #7
    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
    Merci mokochan, effectivement cela marche bien. Bravo ! Mais, après concertation, avec mon tuteur ce dernier voudrait que je fasse encore autrement et que je stocke les résultats sur Matlab. J'ai donc concocté moi-même un code et je n'arrive pas à le faire marcher. Voici ce qu'on m'impose de faire : utiliser la fonction diff qui pour un vecteur donné fait la différence deux à deux des éléments dans l'ordre, par exemple, si :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    V=
    1618
    1619
    1620
    1645
    1653
    Alors LL=diff(V) renvoie donc :

    Maintenant ce qu'on me demande c'est simplement de récupérer le début d'un événement et sa fin dans un vecteur, donc par exemple pour V, je dois récupérer dans R :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    R=
    1618 1620
    1645 1645
    1653 1653
    Voilà, j'ai donc 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
    function R=deb_fin(valeurs_Imp1_liquide)
     
    %On calcule la différence deux à deux consécutivement des élements du
    %vecteur d'entrée et on récupère dans L3 les positions des points à partir
    %desquels la différence est supérieure à 1.
     
    LL=diff(valeurs_Imp1_liquide);
    L3=find(LL>1);
     
     
    debut(1)=valeurs_Imp1_liquide(1); 
    fin(1)=valeurs_Imp1_liquide(L3(1));
    fin(numel(L3)+1)=valeurs_Imp1_liquide(end);
    for i=2:numel(L3), 
        fin(i-1)=valeurs_Imp1_liquide(L3(i-1));
        debut(i)=valeurs_Imp1_liquide(L3(i-1)+1);
     
    end
    R=[debut', fin'];
    Celui-ci n'est pas fonctionnel et je n'arrive pas à le faire marcher : dans LL je récupère les différences deux à deux du vecteur d'entrée et dans L3 je recherche les positions pour lesquelles la différence est supérieure à 1, en l’occurrence en position 3 et 4 sur le vecteur V précédent, c'est-à-dire en fait qu'en position 4 et 5 la différence 4-3 et 5-4 donne un nombre plus grand que 1 : 25 et 8. Voilà et après j'essaye de former les vecteurs debut et fin et de les stocker dans R mais sans succès !

    EDIT

    Après réflexion sur papier, j'essaye le code suivant qui marche mais n'arrive jamais à la fin du vecteur à étudier :

    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
    function R=deb_fin_test(V)
     
    %On calcule la différence deux à deux consécutivement des élements du
    %vecteur d'entrée et on récupère dans L3 les positions des points à partir
    %desquels la différence est supérieure à 1.
     
    LL=diff(V);
     
    %On récupére dans L3 les indices i pour lesquels i+1 est tel que
    %valeurs_Imp1_liquide(i+1) - valeurs_Imp1_liquide(i)>1.
     
    L3=find(LL>1);
     
     
    debut(1)=V(1); 
    fin(1)=V(L3(1));
     
    for i=2:numel(L3), 
     
        debut(i)=V(L3(i-1)+1);
        if ((V(L3(i-1)+2)-V(L3(i-1)+1))>1)
            fin(i)=debut(i);
        else
            fin(i)=V(L3(i-1)+2);
        end
    end
    R=[debut', fin'];
    Il fournit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    R=
    1618 1620
    1645 1645
    Bref, si on peut faire ce que je souhaite avec le code que tu as fait toi, dis-le moi ! En effet, si je reprends ton code comme 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
    function R=detection_ev_test2(V)
    nbEvents = 1;
    dureesEvents = ones(1,length(V));
     
    %Detection des événements
     
    for i = 2:length(V)
        if(V(i)== V(i-1)+1)
            dureesEvents(nbEvents) = dureesEvents(nbEvents)+1;
        else
            nbEvents = nbEvents + 1;
        end
    end
    nbEvents;
    dureesEvents = dureesEvents(1:nbEvents);
     
    %debut, fin
     
    somme = 1;
     
        for j = 1:nbEvents
     
            %On récupère dans valeurs les différents cycles d'événements;
     
            valeurs = V(somme:somme+dureesEvents(j)-1)
            debut=valeurs(1);
            fin=valeurs(end);
            R1=[debut , fin, fin-debut+1];
            somme = somme + dureesEvents(j); 
     
     
        end
        R=R1;
    Je stocke bien dans R ce que je veux mais dans la boucle et de la sorte R varie à chaque fois. J'aurais besoin que R s'incrémente en quelque sorte afin d'obtenir ce qui suit et donc je voudrais que cette fonction me renvoie la matrice R.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    R=
    1618 1620
    1645 1645
    1653 1653

  8. #8
    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 après de multiples labeurs, je pense avoir résolu mon problème et de deux façons en plus :

    Voici le code arrangé de mokochan :

    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
    function y=deb_fin_lemien(V)
    nbEvents = 1;
    dureesEvents = ones(1,length(V));
     
    %Detection des événements
     
    for i = 2:length(V)
        if(V(i)== V(i-1)+1)
            dureesEvents(nbEvents) = dureesEvents(nbEvents)+1;
        else
            nbEvents = nbEvents + 1;
        end
    end
    nbEvents;
    dureesEvents = dureesEvents(1:nbEvents);
     
    RR1=[];
    somme = 1;
        for j = 1:nbEvents
     
            %On récupère dans valeurs les différents cycles d'événements;
     
            valeurs = V(somme:somme+dureesEvents(j)-1);
            debut=valeurs(1);
            fin=valeurs(end);
            R1=[debut , fin, fin-debut+1];
            RR1=[RR1; R1];
            somme = somme + dureesEvents(j); 
     
     
        end
    y=RR1;
    Et le mien qui a en fait l'avantage de ne pas avoir de boucle, ce que mon tuteur veut car je vais devoir traité des vecteurs de millions de valeurs :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function R=deb_fin(valeurs_Imp1_liquide)
    LL=diff(valeurs_Imp1_liquide);
    L3=find(LL>1);
    fin=valeurs_Imp1_liquide(L3); 
    fin(numel(L3)+1)=valeurs_Imp1_liquide(end);
    debut(2:numel(L3)+1)=valeurs_Imp1_liquide(L3+1);
    debut(1)=valeurs_Imp1_liquide(1);
    debut;
    fin;
    R=[debut', fin', fin'-debut'+1];

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

Discussions similaires

  1. [Struts] Problème pour itérer sur un vecteur
    Par vallica dans le forum Struts 1
    Réponses: 5
    Dernier message: 24/04/2006, 15h45
  2. [VBA-A]Détection souris sur un objet.
    Par LiNuXaDDiKt dans le forum VBA Access
    Réponses: 4
    Dernier message: 21/02/2006, 09h13
  3. Chercher un fichier spécifique sur le poste client
    Par Orb Dorb dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 14/10/2005, 18h45
  4. Réponses: 6
    Dernier message: 06/10/2005, 20h54
  5. Zoom sur des vecteurs ou lignes
    Par mat.M dans le forum Algorithmes et structures de données
    Réponses: 7
    Dernier message: 25/11/2002, 10h40

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