39 votes

Constantes dans MATLAB

Je suis devenu propriétaire d'un certain nombre de codes MATLAB et j'ai remarqué qu'il y avait un certain nombre de "chiffres magiques" dispersés dans le code. En général, j'aime créer ces constantes dans des langages tels que C, Ruby, PHP, etc. En cherchant ce problème sur Google, j'ai trouvé que la manière "officielle" d'avoir des constantes est de définir des fonctions qui renvoient la valeur constante. Cela semble compliqué, notamment parce que MATLAB peut être pointilleux lorsqu'il autorise plus d'une fonction par fichier.

Est-ce vraiment la meilleure option ?

Je suis tenté d'utiliser / de fabriquer quelque chose comme le préprocesseur C pour faire cela pour moi. (J'ai trouvé que quelque chose appelé mpp a été fait par quelqu'un d'autre dans une situation similaire, mais il semble abandonné. Le code ne compile pas, et je ne suis pas sûr qu'il répondrait à mes besoins).

1voto

David Steinhauer Points 400

Pour gérer les constantes que je souhaite transmettre à d'autres fonctions, j'utilise une structure :

% Define constants
params.PI = 3.1416;
params.SQRT2 = 1.414;

% Call a function which needs one or more of the constants
myFunction( params ); 

Ce n'est pas aussi propre que les fichiers d'en-tête C, mais cela fait l'affaire et évite les globaux MATLAB. Si vous souhaitez que les constantes soient toutes définies dans un fichier distinct (par exemple, getConstants.m), ce serait également facile :

params = getConstants();

0voto

Nathan Donnellan Points 308

N'appelez pas une constante en utilisant myClass.myconst sans créer une instance au préalable ! À moins que la vitesse ne soit pas un problème. J'avais l'impression que le premier appel à une propriété constante créait une instance et que tous les appels ultérieurs faisaient référence à cette instance, ( Propriétés à valeurs constantes ), mais je ne crois plus que ce soit le cas. J'ai créé une fonction de test très basique de la forme :

tic;
for n = 1:N
    a = myObj.field;
end
t = toc;

Avec des classes définies comme :

classdef TestObj
    properties
        field = 10;
    end
end

ou :

classdef TestHandleObj < handle
    properties
        field = 10;
    end
end

ou :

classdef TestConstant
    properties (Constant)
        field = 10;
    end
end

Pour différents cas d'objets, de manipulations d'objets, d'objets imbriqués, etc. (ainsi que pour les opérations d'affectation). Notez que ce sont tous des scalaires ; je n'ai pas étudié les tableaux, les cellules ou les chars. Pour N = 1.000.000 mes résultats (pour le temps total écoulé) étaient :

Access(s)  Assign(s)  Type of object/call
  0.0034    0.0042    'myObj.field' 
  0.0033    0.0042    'myStruct.field'  
  0.0034    0.0033    'myVar'                   //Plain old workspace evaluation
  0.0033    0.0042    'myNestedObj.obj.field'   
  0.1581    0.3066    'myHandleObj.field'   
  0.1694    0.3124    'myNestedHandleObj.handleObj.field'   
 29.2161         -    'TestConstant.const'      //Call directly to class(supposed to be faster)
  0.0034         -    'myTestConstant.const'    //Create an instance of TestConstant
  0.0051    0.0078    'TestObj > methods'       //This calls get and set methods that loop internally
  0.1574    0.3053    'TestHandleObj > methods' //get and set methods (internal loop)

J'ai également créé une classe Java et effectué un test similaire :

 12.18     17.53      'jObj.field > in matlab for loop'
  0.0043    0.0039    'jObj.get and jObj.set loop N times internally'

La surcharge liée à l'appel de l'objet Java est élevée, mais à l'intérieur de l'objet, les opérations simples d'accès et d'affectation sont aussi rapides que pour les objets matlab ordinaires. Si vous voulez un comportement de référence au démarrage, Java peut être la voie à suivre. Je n'ai pas étudié les appels d'objets dans les fonctions imbriquées, mais j'ai vu des choses bizarres. De plus, le profileur est nul pour beaucoup de ces choses, c'est pourquoi j'ai décidé de sauvegarder manuellement les temps.

Pour référence, la classe Java utilisée :

public class JtestObj {
    public double field = 10;

    public double getMe() {
        double N = 1000000;
        double val = 0;
        for (int i = 1; i < N; i++) {
            val = this.field;
        }

        return val;
     }

     public void setMe(double val) {
        double N = 1000000;
        for (int i = 1; i < N; i++){
            this.field = val;
        }
     }
  }

Dans le même ordre d'idées, voici un lien vers un tableau des constantes du NIST : table ascii et une fonction matlab qui renvoie une structure avec les valeurs listées : Matlab FileExchange

0voto

J'utilise un script avec des constantes simples en majuscules et j'inclus ce script dans d'autres script qui en ont besoin.

LEFT  = 1;
DOWN  = 2;
RIGHT = 3; etc.

Le fait qu'elles ne soient pas constantes ne me dérange pas. Si j'écris "GAUCHE=3", je serai peut-être complètement stupide et, de toute façon, il n'y a pas de remède contre la stupidité, alors je ne m'en soucie pas. Mais je déteste vraiment le fait que cette méthode encombre mon espace de travail avec des variables que je n'aurais jamais à inspecter. Et je n'aime pas non plus utiliser des phrases comme "turn(MyConstants.LEFT)" parce que cela fait des déclarations plus longues de plusieurs millions de caractères, rendant mon code illisible.

Ce dont j'aurais besoin, ce n'est pas d'une variable mais d'une possibilité d'avoir de véritables constantes pré-compilateur. C'est-à-dire des chaînes de caractères qui sont remplacées par des valeurs juste avant d'exécuter le code. C'est ainsi que cela devrait être. Une constante ne devrait pas nécessairement être une variable. Elle n'est destinée qu'à rendre votre code plus lisible et plus facile à maintenir. MathWorks : S'IL TE PLAÎT, S'IL TE PLAÎT, S'IL TE PLAÎT. Cela ne doit pas être si difficile à implémenter. . .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X