[Matlab] Simplification d'une boucle

Le problème exposé dans ce sujet a été résolu.

Bonjour à tous,

Je poste ce message plutôt à titre d’information personnelle car ça fait déjà ce que je veux faire mais comme je sais que Matlab est truffé de raccourcis très puissants, je me demandais s’il n’y avait pas moyen de ré-écrire cette boucle en deux-trois lignes.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
for i=1:row
    if X(i)<0
        threshold=i;
        break
    end
end

for i=threshold:row
    X(i) = 0;
    A(i) = A(threshold);
end

Pour vous mettre dans le contexte, $X$ est un vecteur avec des concentrations mais physiquement une concentration ne peut pas être négative. Je cherche donc le moment où elle devient négative et je met des zéros. Mon vecteur $A$ quant à lui doit rester constant à la dernière valeur trouvée (imaginons X devient négatif quant A vaut 100, on laisse A jusqu’à la fin). row désigne le nombre de ligne dans ces vacteurs ($A$ et $X$ ont la même taille).

Je sais que pour tout mettre à zéro il suffit de faire X(X<0) = 0 mais après je récupère pas l’index (du moins je pense?) donc je vois pas comment gérer $A$.

Avez-vous des idées ou ça vous paraît déjà "optimal" ?

Merci !

+0 -0

Merci pour ta réponse! J’ai tenté de faire ça mais ça ne semble pas fonctionner. Qu’entends-tu par end? En attendant, j’ai réussi à la simplifier en une seule boucle (je sais pas si c’est vraiment mieux!):

1
2
3
4
5
6
7
for i=1:row
    if X(i)<0
        X(i:row) = 0;
        A(i:row) = A(i)
        break
    end
end

Merci pour ta réponse! J’ai tenté de faire ça mais ça ne semble pas fonctionner.

Qu’est-ce que tu as comme message d’erreur ? Il y a des chances que la syntaxe d’@dr1 soit fausse, même si le principe est bon.

Qu’entends-tu par end?

sotibio

end est un mot clé qui désigne le dernier élement du vecteur. Par exemple, si a a 10 éléments, alors a(end) est équivalent à a(10).

En attendant, j’ai réussi à la simplifier en une seule boucle (je sais pas si c’est vraiment mieux!):

1
2
3
4
5
6
7
for i=1:row
    if X(i)<0
        X(i:row) = 0;
        A(i:row) = A(i)
        break
    end
end
sotibio

Tu peux sûrement savoir toi-même si c’est mieux :

  • Est-ce que ça fait toujours le job ?
  • Est-ce que c’est plus lisible ?
  • Est-ce que c’est plus rapide, si la vitesse importe ?
+0 -0

Il me dit:

1
2
3
4
In an assignment  A(:) = B, the number of elements in A and B must be the same.

Error in modeling_project001 (line 57)
A(X<0) = A(X>=0);

Ma nouvelle boucle fait toujours le job, c’est un peu plus rapide mais rien de bien fou non plus!

+0 -0

Ben t’as pas mis le (end)

EDIT : au fait, c’est peut être a(x<0) = a(x<0)(1) que tu veux plutôt que a(x<0) = a(x>=0)(end). M’enfin, l’idée est la même.

+0 -0

J’ai testé avec le (end) mais ça ne fonctionne pas non plus.

En mettant:

1
2
A(X<0) = A(X>=0)(1);
X(X<0) = 0;

Ça me renvoit aussi la même erreur:

1
2
Error: File: modeling_project001.m Line: 57 Column: 10
()-indexing must appear last in an index expression.

Googler ton erreur renvoie ceci en premier résultat. Il faut apprendre à être un peu autonome, sinon tu ne progresseras pas.

En fait je suis en train de me dire qu’une solution un peu plus efficace serait plutôt de faire comme ça (si row est bien len(x)) :

1
2
3
i = find(x<0, 1)
x(i:row) = 0
a(i:row) = a(i)
+0 -0

Merci à vous deux! Ça fonctionne effectivement bien maintenant et c’est de loin la méthode qui fait que le code est bien plus rapide (la dernière proposée par adri1)… Comme quoi les fonctions développées par Matlab sont assez puissante.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte