Aller au contenu

matlab et les boucles


Messages recommandés

Bonjour,

j'ai un petit problème avec les boucles :

for i=1:length(Y)

if Y<=-0.1

A(i,1)=1

else

A(i,1)=0

end

end

voilà la boucle. Elle a pour but de regarder quand la ligne i de Y (qui est l'amplitude d'un fichier wav issue d'un wavread) est inférieure à -0.1. Si c'est le cas, elle transforme ,dans une matrice A de même longueur, la ligne correspondante en 1 ou en 0 si la condition est réalisée de sorte à avoir un semblant de signal carré.

mais le problème c'est que Y comporte plus de 710000 points et je peux difficilement la rétrécir. Et à chaque boucle, la boucle me réecrit la matrice A qui fait 710000 points et donc ceci 710000 fois donc c'est interminable !!

J'arrive pas à trouver un moyen pour traiter les lignes une par une pour que la matrice Y soit examiner q'une seule fois

pouvez vous m'aider? pas me sortir un code, mais m'expliquer une autre façon de procéder

Merci

Lien vers le commentaire
Partager sur d’autres sites

  • 3 semaines après...

je suppose que "if Y<=-0.1" c'est plutot "if Y(i)<=-0.1"

dans ton exemple, tu n'as qu'une boucle sur un vecteur, 710000 if ça ne prend pas bien longtemps sur une machine correcte (<10sec sur mon PC). Pourquoi parles-tu de matrice ?

Par contre met des points virgule après "A(i,1)=1" et "A(i,1)=0" sinon effectivement ça va prendre des plombes pour tout afficher.

si tu veux aller plus vite, tu dois compiler (avec mex ou mcc) je dirais.

Lien vers le commentaire
Partager sur d’autres sites

  • 3 mois après...

Je sais que ce topic est un peu vieux mais je pense que je peux apporter quelques infos utiles.

Si le programme est lent je pense aussi que c'est à cause du "if Y <=-0.1" au lieu de "if Y(i) <=-0.1".

Quand on écrit une condition sur une matrice ou un vecteur, matlab va la vérifier pour tous les éléments. Il faut aussi savoir que quand on fait un test sur toute une matrice après un if, matlab ne considère la condition vérifiée que si TOUS les éléments vérifient la condition (il utilise implicitement la fonction all() ).

Ca veut dire qu'à chaque itération tous les éléments étaient revérifiés, ce qui fait qu'en réalité tu as fait 504.1e9 tests plus 710000 appels implicites à la fonction all().

Et comme à chaque fois le résultat était forcément le même (test sur tout Y) je suis prêt à parier que tous les éléments de ta matrice A(:,1) sont égaux (donc ton programme ne marche pas).

Voila pour l'explication des problèmes.

Tu n'as plus qu'à corriger en n'oubliant pas d'initialiser la matrice A avant la boucle.

Maintenant si tu as envie d'écrire quelque chose de beaucoup plus joli et efficace (parce que toi aussi tu sais que les boucles for sous matlab, çaylemal :ouioui: ) tu peux remplacer tout ton code par :

A(:,1) = double( Y(:) <= -0.1 );

Ca exploite ce que j'ai expliqué concernant les tests sur des matrices : "Y <= -0.1" renvoie une matrice de booléens de la même taille que Y qui contient TRUE ou FALSE pour chaque élément suivant le résultat du test sur l'élément de Y qui correspond. En interne ils sont codés par des 1 et des 0 de type logique qu'on convertit en type numérique avec la fonction "double".

Il n'est pas forcément nécessaire de convertir, matlab le fait de manière implicite dans les calculs. Mais certaines fonctions risquent de planter avec des booléens.

En faisant ça on utilise les routines internes de matlab (généralement optimisées en C++ ou fortran, donc très rapides) et on évite de faire une boucle for ( çaylemal :oops: ).

ps : Les notations un peu bizarres que j'ai utilisées ( "A(:,1)", "Y(:)" ) sont là pour éviter les problèmes de dimension. On peut s'en passer si A est un vecteur.

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

×
×
  • Créer...