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 :

Boucle for et multiplication de valeurs qui se suivent dans un vecteur [Débutant]


Sujet :

MATLAB

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Transports

    Informations forums :
    Inscription : Janvier 2014
    Messages : 44
    Points : 34
    Points
    34
    Par défaut Boucle for et multiplication de valeurs qui se suivent dans un vecteur
    Bonjour,

    J'éprouve quelques soucis pour créer un vecteur (vecteur 2d) a partir d'une multiplication de valeurs qui se suivent dans un autre vecteur. Je m'explique :

    A partir du vecteur S=[a b c d e f] (ou a b c d e f sont des cellules de valeurs), je souhaite créer un vecteur de cellules Hc=[(a*b)^1/2;(c*d)^1/2;(e*f)^1/2] pour chaque frequence f.

    j'ai donc créer le code suivant :

    f represente mon vecteur frequence

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Hc=zeros(N,1,f2);
     
    for f=1:f2;
        for e=1:5;
            for g=1:3;
                Hc(g,1,f)=sqrt(S{1,e}.y_values.values(1,f)*S{1,e+1}.y_values.values(1,f2));
            end
        end
    end
    Cependant au résultat, Matlab va calculer une meme valeur aux 3 lignes de mon vecteur qui changera pour chaque frequence. Pouvez vous m'indiquer ou je me suis trompé svp ?

    Merci d'avance.

  2. #2
    Membre éprouvé
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Points : 1 277
    Points
    1 277
    Par défaut
    Bonjour,

    Difficile de faire le lien entre ta formule et ton code. Peut être le second terme indexé par f2, alors que f2 ne varie pas dans tes boucles.

    En particulier, tu parles de vecteurs alors que tu manipules des cell-arrays contenant des structures ! Si tes données sont homogènes, il serait bien plus agréable de te débarrasser du cell array et des structures qui contiennent les numériques et de travailler sur une matrice.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    V= cellfun(@(x) x.y_values.values,S,'uni',0);
    V= cat(1,V{:});
    une fois que tu as la matrice V des valeurs, plus besoin de boucles (les boucles seront faites par matlab sur les couches internes).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Hc= sqrt( [V(:,1).*V(:,2) , V(:,3).*V(:,4), V(:,5).*V(:,6) ] );

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Transports

    Informations forums :
    Inscription : Janvier 2014
    Messages : 44
    Points : 34
    Points
    34
    Par défaut
    Citation Envoyé par VV33D Voir le message
    Bonjour,

    Difficile de faire le lien entre ta formule et ton code. Peut être le second terme indexé par f2, alors que f2 ne varie pas dans tes boucles.

    En particulier, tu parles de vecteurs alors que tu manipules des cell-arrays contenant des structures ! Si tes données sont homogènes, il serait bien plus agréable de te débarrasser du cell array et des structures qui contiennent les numériques et de travailler sur une matrice.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    V= cellfun(@(x) x.y_values.values,S,'uni',0);
    V= cat(1,V{:});
    Effectivement, la technique du cellfun me parait plus qu'intéressante, merci pour l'astuce. Ayant des connaissances plus que limitées sur le repertoire de fonctions que possede MATLAB, j'essayais de faire avec ce que je connaissais deja... ^^




    Citation Envoyé par VV33D Voir le message
    une fois que tu as la matrice V des valeurs, plus besoin de boucles (les boucles seront faites par matlab sur les couches internes).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Hc= sqrt( [V(:,1).*V(:,2) , V(:,3).*V(:,4), V(:,5).*V(:,6) ] );



    Pour Hc, je travaille avec des fréquences. C'est a dire qu'a chaque fréquence (matérialisée par f dans la boucle de mon code), je dois avoir un vecteur Hc de taille 3x1 (que j'essaye de calculer avec le code que j'essaye de programmer) multidimensionnelle (ou la troisieme dimension serait la frequence).

    Or avec la formule de Hc que tu me donnes dans ton code, j'obtiens une matrice 6x3 sans mes frequences, ce qui ne correspond pas a ce que je cherche a obtenir. J'ai essayé ca du coup :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Hc=zeros(N,f2);
     
    for f=1:f2;
        for g=1:5;
        Hc(:,f)=sqrt( [V(g,f).*V(g+1,f)]);
        end
    end
    Mai sans resultats concluants...

  4. #4
    Membre éprouvé
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Points : 1 277
    Points
    1 277
    Par défaut
    Je croyais que la fréquence correspondait à ta dimension 2, car dans ta triple boucle, tu ne te sers pas de la dimension 2 (toujours indexée par 1).
    Si V et Hc ont 3 dimensions, il suffit de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Hc= sqrt( cat(2, V(:,1,:).*V(:,2,:) , V(:,3,:).*V(:,4,:), V(:,5,:).*V(:,6,:) ) );
    La partie délicate consiste en fait à transformer tes cell/struct en 3D-array, en étant sur d'identifier ce que contient chaque dimension. D'après ce que je comprends,
    - S n'a qu'une dimension (enquel le 1er indice 1 est optionnel S{e} <=> S{1,e} ).
    - Quelque soit e, S{1,e}.y_values.values est un vecteur et pas une matrice (puisque tu n'utilises que 1 en 1er indice).
    Et donc je ne vois pas d'ou vient ta dimension fréquence.

    Décris précisément les dimensions de S et des S{e}.y_values.values

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Transports

    Informations forums :
    Inscription : Janvier 2014
    Messages : 44
    Points : 34
    Points
    34
    Par défaut
    Ah effectivement j'ai du me tromper au niveau des dimensions. Je vais tenter de te clarifier tout ca :

    Hc doit etre une matrice de taille 3x1025 (1025 sera multiplié par un increment pour définir la bande de fréquence)

    S{e}.y_values.values sont des vecteurs 1x1025.

    et S est une cellule 1x6.

  6. #6
    Membre éprouvé
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Points : 1 277
    Points
    1 277
    Par défaut
    Donc j'avais raison, pas besoin de passer par des 3D arrays. Normalement après
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    V= cellfun(@(x) x.y_values.values,S,'uni',0);
    V= cat(1,V{:});
    V est de taille 6*1025

    Ensuite (j'ai inversé les indices vu que tu travailles "en ligne")
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Hc= sqrt( [V(1,:).*V(2,:) , V(3,:).*V(4,:), V(5,:).*V(6,:) ] );
    est de taille 3*1025

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Transports

    Informations forums :
    Inscription : Janvier 2014
    Messages : 44
    Points : 34
    Points
    34
    Par défaut
    Ok, ca marche. Parfait ! Merci.

    Le seul petit truc c'est que je dois l'incrémenter en fonction des variables que j'utilise. En fait Hc et V sont conditionés par le nombres de variables que je rentre. Disons que ces variables proviennent de microphones dont les signaux sont recoltés. Si j'utilise 3 micros Hc aura 3 lignes et V 6 lignes, si j'en utilise 4 Hc aura 4 lignes et V 12 lignes, N micro = N lignes pour Hc et N*(N-1) lignes pour V etc...

    Du coup j'aimerais generaliser Hc en fonction des variables que j'aurais rentré. Disons que N est le nombre de microphones que j'utilise. J'aimerais utiliser une boucle for pour generaliser tout ca et conditionner le nombre de lignes et les valeurs de Hc, comme par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     for g=1:u-1;
         for h=1:N;
             Hc(h,:)= sqrt([V(g,:).*V(g+1,:)]);
         end
    end
    u serait le nombre de lignes de V et N le nombre de microphones utilisés.

    Le probleme c'est que j'obtiens ca Nom : Untitled.jpg
Affichages : 788
Taille : 89,5 Ko

  8. #8
    Membre éprouvé
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Points : 1 277
    Points
    1 277
    Par défaut
    Mon code marche quelque soient les dimensions, pas besoin de changer quoi que ce soit.

    Encore une fois, la force de matlab est d'avoir des opérations vectorisées (cellfun,produit terme à terme .*, sqrt() appliqué sur chaque élément...).
    Utilisées avec parcimonie, ces opérations sont plus performantes et donnent un code plus lisible. Pas besoin de recourir à size() ni à for, Matlab fait ça tout seul.

  9. #9
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Transports

    Informations forums :
    Inscription : Janvier 2014
    Messages : 44
    Points : 34
    Points
    34
    Par défaut
    Pardonne mon ignorance mais en lisant ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Hc= sqrt( [V(1,:).*V(2,:) ; V(3,:).*V(4,:); V(5,:).*V(6,:) ] );
    Je comprends que Hc ne peut avoir que 3 lignes et V 6 lignes peut importe le nombres de micros que j'utilise. Je me trompe ?

    En tout cas c'est clair que ca raccourci largement le nombre de lignes, merci infiniment pour tes astuces et ta patience.

  10. #10
    Membre éprouvé
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Points : 1 277
    Points
    1 277
    Par défaut
    Tu as raison

    Tu peux transformer ce passage en boucle, par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Hc= nan(size(V,1)/2, size(V,2)); % preallocation
    for p=1:(size(V,1)/2)
        Hc(p,:) = V(p,:) .* V(p+1,:);
    end
    ou encore
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Hc= arrayfun( @(i) V(i,:).*V(i+1,:), 1:2:size(V,1));

    Si tu voulais le vectoriser, il faudrait un truc du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    [P,Q]= size(V);
    V3d= reshape(V,[P/2,2,Q]); % rajoute une 3eme dimension pour diviser les lignes pairs et impaires en 2
    Hc= prod(Hc,2); % produit sur la dimension 2, ie row i * row i+1
    Hc= sqrt(squeeze(Hc));
    A tester cependant, je n'arrive jamais à savoir de mémoire si reshape va empiler dans le sens souhaité (c'est soit ca, soit reshape(,[2 P/2 q]) et prod(,1))

  11. #11
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Transports

    Informations forums :
    Inscription : Janvier 2014
    Messages : 44
    Points : 34
    Points
    34
    Par défaut
    Ça fonctionne parfaitement, merveilleux. Merci infiniment pour ton aide et ta patience !

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

Discussions similaires

  1. [AC-2010] Boucle For/Next et While/Wend qui plante Access
    Par Dixies dans le forum VBA Access
    Réponses: 2
    Dernier message: 16/02/2014, 14h07
  2. [XL-2003] boucle For avec multiple conditions d'arret
    Par yvespi dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 26/05/2010, 09h30
  3. Réponses: 10
    Dernier message: 12/09/2008, 10h09
  4. Réponses: 13
    Dernier message: 27/11/2007, 11h06
  5. [VB6] boucle for avec liste de valeur defini
    Par Morpheus2144 dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 06/04/2006, 18h12

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