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 :

Avertissement "Variable might be set by a nonscalar operator" [Débutant]


Sujet :

MATLAB

  1. #1
    Responsable Qt & Livres


    Avatar de dourouc05
    Homme Profil pro
    Ingénieur de recherche
    Inscrit en
    Août 2008
    Messages
    26 675
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur de recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2008
    Messages : 26 675
    Points : 188 676
    Points
    188 676
    Par défaut Avertissement "Variable might be set by a nonscalar operator"


    Je dois évaluer la valeur d'une fonction définie par morceau en vue d'en faire un graphique. Le tout se déroule bien, sauf que j'ai un avertissement que je ne parviens pas à comprendre. La fonction semble se comporter correctement. Voici le code incriminé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
            function x = evaluate(v_CE)
                v_CE_max = 0.6;
     
                v_CE = v_CE ./ v_CE_max; % normalisation
     
                if (v_CE <= 0)
                    x = (v_CE + 1) ./ ((-6.7 .* v_CE) + 1); 
                else
                    x = ((1.8 .* v_CE) + 0.017) ./ (v_CE + 0.017); 
                end
            end
    L'avertissement apparaît sur la variable v_CE au niveau du if. J'ai déjà tenté Google, mais il ne me donne aucune réponse sur ce message .

    J'utilise MATLAB 2010b, pour Windows en 64 bits.

    Quelqu'un pourrait-il m'apporter un élément de réponse ?


  2. #2
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 316
    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 316
    Points : 52 948
    Points
    52 948
    Par défaut
    Tout vient de la ligne suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     v_CE = v_CE ./ v_CE_max; % normalisation
    Le point qui précède le signe "diviser" laisse penser à MATLAB que v_CE est un tableau et non pas un scalaire. Car l'opérateur arithmétique que tu utilises est "réservé" aux opérations éléments par éléments pour les tableaux. Et MATLAB t'averti donc que la condition "if" est mal écrite pour un tableau.

    Bien entendu, dans l'absolu ton code fonctionne pour un scalaire, mais tu devrais utiliser les opérateurs arithmétiques matriciels (sans le point) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     v_CE = v_CE / v_CE_max; % normalisation
    Sauf si v_CE est bien un tableau (ou du moins un vecteur)... mais dans ce cas, c'est la condition qui suit qui sera fausse.

  3. #3
    Responsable Qt & Livres


    Avatar de dourouc05
    Homme Profil pro
    Ingénieur de recherche
    Inscrit en
    Août 2008
    Messages
    26 675
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur de recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2008
    Messages : 26 675
    Points : 188 676
    Points
    188 676
    Par défaut
    v_CE est généralement un vecteur, qui sera utilisé pour le graphe de la fonction. J'ai néanmoins remplacé le ./ par /, ce qui enlève l'erreur et donne le même résultat. Si j'ai bien compris, ça permet de diviser chaque élément du vecteur (comme dans matrix + 3, on ajoute 3 à chaque élément de la matrice matrix).

    Par contre, dans la division dans chaque cas du if, je suis obligé de garder ./, car j'ai des vecteurs de chaque côté, ce qui fera la division élément par élément. C'est bien ça ?

    Maintenant, quand tu dis que la condition sera fausse, comment faire alors, sachant que j'ai deux expressions différentes à évaluer pour la fonction ? J'utilise un for pour itérer dans tout le vecteur ? Ou bien c'est censé très bien fonctionner comme ça ?

  4. #4
    Modérateur

    Homme Profil pro
    Ingénieur en calculs scientifiques
    Inscrit en
    Août 2007
    Messages
    4 639
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Ingénieur en calculs scientifiques

    Informations forums :
    Inscription : Août 2007
    Messages : 4 639
    Points : 7 614
    Points
    7 614
    Par défaut
    Salut,

    Citation Envoyé par dourouc05 Voir le message
    v_CE est généralement un vecteur, qui sera utilisé pour le graphe de la fonction. J'ai néanmoins remplacé le ./ par /, ce qui enlève l'erreur et donne le même résultat. Si j'ai bien compris, ça permet de diviser chaque élément du vecteur (comme dans matrix + 3, on ajoute 3 à chaque élément de la matrice matrix).
    Exactement

    Citation Envoyé par dourouc05 Voir le message
    Par contre, dans la division dans chaque cas du if, je suis obligé de garder ./, car j'ai des vecteurs de chaque côté, ce qui fera la division élément par élément. C'est bien ça ?
    Oui, à l'intérieur du if, pour faire une division élément par élément, il faut obligatoirement garder le "./".

    Citation Envoyé par dourouc05 Voir le message
    Maintenant, quand tu dis que la condition sera fausse, comment faire alors, sachant que j'ai deux expressions différentes à évaluer pour la fonction ? J'utilise un for pour itérer dans tout le vecteur ? Ou bien c'est censé très bien fonctionner comme ça ?
    Je ne sais pas pourquoi Dut pense que la condition peut-être fausse, pour moi, elle fonctionne aussi avec un tableau (donc a priori avec un vecteur). Dans la doc du if de matlab :
    Nonscalar Expressions

    If the evaluated expression yields a nonscalar value, then every element of this value must be true or nonzero for the entire expression to be considered true. For example, the statement if (A < B) is true only if each element of matrix A is less than its corresponding element in matrix B
    Par contre si MATLAB reconnait v_CE comme un tableau, tu devrais à nouveau avoir un avertissement sur fait d'utiliser "if" avec autre chose qu'un scalaire mais ce message peut-etre ignoré.
    Si tu es allergique au avertissement dans l'éditeur, tu peux utiliser :
    La fonction all renvoie 1 si tous les éléments sont inférieurs ou égaux à 0, 0 sinon.

    Par contre c'est le premier message que je vois dans ce forum ou le posteur s'inquiète des messages d'avertissement dans l'éditeur. A noter qu'une ligne indiqué par un message d'avertissement provoquera rarement une erreur (comme c'est souvent indiqué dans l'explication du message d'avertissement : "This message can be incorrect if the operator is overloaded"), mais c'est une bonne idée de se renseigner dessus

  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 316
    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 316
    Points : 52 948
    Points
    52 948
    Par défaut
    Citation Envoyé par magelan Voir le message
    Je ne sais pas pourquoi Dut pense que la condition peut-être fausse, pour moi, elle fonctionne aussi avec un tableau (donc a priori avec un vecteur).
    J'ai sans doute mal compris la question... je pensais que le test permettait de discriminer chaque valeur du vecteur v_CE donnant des valeurs de x différentes.

    Quelque chose comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    for n = 1:numel(v_CE)
        if v_CE(n)>=0
            x(n) = ...
        else
            x(n) = ...
        end
    end
    Mais dans le cas où l'on considère la vecteur dans son ensemble, le code fonctionnera bien... sauf que pour ma part je trouve l'utilisation de ANY ou ALL plus explicite.

  6. #6
    Responsable Qt & Livres


    Avatar de dourouc05
    Homme Profil pro
    Ingénieur de recherche
    Inscrit en
    Août 2008
    Messages
    26 675
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur de recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2008
    Messages : 26 675
    Points : 188 676
    Points
    188 676
    Par défaut
    Citation Envoyé par magelan Voir le message
    Par contre c'est le premier message que je vois dans ce forum ou le posteur s'inquiète des messages d'avertissement dans l'éditeur. A noter qu'une ligne indiqué par un message d'avertissement provoquera rarement une erreur (comme c'est souvent indiqué dans l'explication du message d'avertissement : "This message can be incorrect if the operator is overloaded"), mais c'est une bonne idée de se renseigner dessus
    Je n'ai jamais aimé avoir des avertos, souvent signe d'un code "un peu" mal fait (surtout en C) .

    Citation Envoyé par Dut Voir le message
    J'ai sans doute mal compris la question... je pensais que le test permettait de discriminer chaque valeur du vecteur v_CE donnant des valeurs de x différentes.

    Quelque chose comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    for n = 1:numel(v_CE)
        if v_CE(n)>=0
            x(n) = ...
        else
            x(n) = ...
        end
    end
    Mais dans le cas où l'on considère la vecteur dans son ensemble, le code fonctionnera bien... sauf que pour ma part je trouve l'utilisation de ANY ou ALL plus explicite.
    Ici, je peux passer un vecteur comme -0.6:0.01:0.6, c'est-à-dire que j'aurai des valeurs qui utilisent un cas et d'autres l'autre, tout ça avec le même vecteur d'entrée. J'ai donc pris un beau for (ils sont plus beaux qu'en C, y'a pas à dire ) qui semble faire ce qu'on veut de lui :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
                for i = 1:numel(v_CE)
                    if (v_CE(i) <= 0)
                        x(i) = (v_CE(i) + 1) / ((-6.7 .* v_CE(i)) + 1); 
                    else
                        x(i) = ((1.8 .* v_CE(i)) + 0.017) / (v_CE(i) + 0.017); 
                    end
                end
    Est-ce que ce code donne bien ce que je veux ? C'est-à-dire que j'ai deux expressions analytiques en fonction de la valeur de l'élément de v_CE, selon qu'il est négatif ou positif. Au niveau du graphe, j'ai maintenant une fonction continue, ce qui a un sens dans l'application (cette fonction sert à modéliser la force exercée par un groupe de muscles sur la jambe).


  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 316
    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 316
    Points : 52 948
    Points
    52 948
    Par défaut
    L'opérateur .* n'est pas nécessaire vu que tu manipules maintenant des données scalaires...
    Il y a aussi quelques parenthèses inutiles...

  8. #8
    Responsable Qt & Livres


    Avatar de dourouc05
    Homme Profil pro
    Ingénieur de recherche
    Inscrit en
    Août 2008
    Messages
    26 675
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur de recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2008
    Messages : 26 675
    Points : 188 676
    Points
    188 676
    Par défaut
    C'est vrai que MATLAB connaît les priorités des opérateurs . Embelli un peu, le code ressemble maintenant à :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
                for i = 1:numel(v_CE)
                    if (v_CE(i) <= 0)
                        x(i) = (v_CE(i) + 1) / (-6.7 * v_CE(i) + 1); 
                    else
                        x(i) = (1.8 * v_CE(i) + 0.017) / (v_CE(i) + 0.017); 
                    end
                end
    Je ne pense pas qu'on peut aller plus loin, non ?

  9. #9
    Modérateur

    Homme Profil pro
    Ingénieur en calculs scientifiques
    Inscrit en
    Août 2007
    Messages
    4 639
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Ingénieur en calculs scientifiques

    Informations forums :
    Inscription : Août 2007
    Messages : 4 639
    Points : 7 614
    Points
    7 614
    Par défaut
    Une petite optimisation rapide à mettre en place, c'est la préallocation de mémoire. Mais normalement l'éditeur de MATLAB a du t'avertir.

  10. #10
    Responsable Qt & Livres


    Avatar de dourouc05
    Homme Profil pro
    Ingénieur de recherche
    Inscrit en
    Août 2008
    Messages
    26 675
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur de recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2008
    Messages : 26 675
    Points : 188 676
    Points
    188 676
    Par défaut
    Euh, non, ça, il ne m'a pas prévenu ! Pas très grave, je viens de le faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
                x = zeros(1, numel(v_CE)); 
     
                for i = 1:numel(v_CE)
                    if (v_CE(i) <= 0)
                        x(i) = (v_CE(i) + 1) / (-6.7 * v_CE(i) + 1); 
                    else
                        x(i) = (1.8 * v_CE(i) + 0.017) / (v_CE(i) + 0.017); 
                    end
                end

  11. #11
    Expert confirmé
    Avatar de duf42
    Homme Profil pro
    Formateur en informatique
    Inscrit en
    Novembre 2007
    Messages
    3 111
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Formateur en informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 111
    Points : 4 661
    Points
    4 661
    Par défaut
    Bonjour,

    Pour optimiser encore un petit peu, on peut supprimer la boucle:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    x = zeros(1, numel(v_CE)); 
    x(v_CE<=0) = (v_CE(v_CE<=0) + 1) ./ (-6.7 * v_CE(v_CE<=0) + 1);
    x(v_CE>0) = (1.8 * v_CE(v_CE>0) + 0.017) ./ (v_CE(v_CE>0) + 0.017);
    Duf

  12. #12
    Responsable Qt & Livres


    Avatar de dourouc05
    Homme Profil pro
    Ingénieur de recherche
    Inscrit en
    Août 2008
    Messages
    26 675
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur de recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2008
    Messages : 26 675
    Points : 188 676
    Points
    188 676
    Par défaut
    ! (C'est fou ce qu'on peut apprendre sur MATLAB en un rien de temps !).


  13. #13
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 316
    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 316
    Points : 52 948
    Points
    52 948
    Par défaut
    Citation Envoyé par duf42 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    x = zeros(1, numel(v_CE)); 
    x(v_CE<=0) = (v_CE(v_CE<=0) + 1) ./ (-6.7 * v_CE(v_CE<=0) + 1);
    x(v_CE>0) = (1.8 * v_CE(v_CE>0) + 0.017) ./ (v_CE(v_CE>0) + 0.017);
    ou :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    x = zeros(1, numel(v_CE)); 
    idx = v_CE<=0; 
    x(idx) = (v_CE(idx) + 1) ./ (-6.7 * v_CE(idx) + 1);
    x(~idx) = (1.8 * v_CE(~idx) + 0.017) ./ (v_CE(~idx) + 0.017);
    Ou encore :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    x = (v_CE + 1) ./ (-6.7 * v_CE + 1);
    idx = v_CE>0; 
    x(idx) = (1.8 * v_CE(idx) + 0.017) ./ (v_CE(idx) + 0.017);
    Ou encore... pour les adeptes du "tout en une ligne" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    x = (v_CE + 1) ./ (-6.7 * v_CE + 1) .* (v_CE<=0) + (1.8 * v_CE + 0.017) ./ (v_CE + 0.017) .* (v_CE>0);

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

Discussions similaires

  1. problème de Wshshell.run avec quotes & variable
    Par frenchlion dans le forum VBScript
    Réponses: 8
    Dernier message: 29/11/2011, 17h35
  2. Réponses: 2
    Dernier message: 27/07/2011, 14h31
  3. Avertissement sur variable assignée
    Par soso78 dans le forum VB.NET
    Réponses: 12
    Dernier message: 13/01/2008, 02h15

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