Matlab accepte-t-il les indices non entiers?

bien sûr que non! ...Ou est-il? Nous allons faire quelques tests.

Définir x = [10 20 30 40 50]. Puis l'un des énoncés suivants, comme prévu, donne une erreur dans Matlab ( les indices en indice doivent être des entiers réels positifs ou des valeurs logiques):

>> x(1.2)
>> x(-0.3)
>> x([1.4 2 3])
>> x([1.4 2.4 3.4])
>> x([1.4:4])
>> x(end/2)

cependant, les valeurs non-entières sont acceptées dans deux indices. Tous les travaux suivants dans les versions récentes de Matlab, bien qu'avec un avertissement (les opérandes entières sont requis pour l'opérateur du côlon lorsqu'il est utilisé comme index).

>> x(1.2:3)
ans =
    10    20

>> x(0.4:3)
ans =
    10    10    20

>> x(0.6:3)
ans =
    10    20    30

>> x(1.2:0.7:5)
ans =
    10    20    30    30    40    50

>> x(-0.4:3)
ans =
    10    10    20    30

cela fonctionne aussi si l'expression de colon inclut end:

>> x(1.5:end-2)
ans =
    20    30

>> x(1.5:end/6:end-1)
ans =
    20    20    30    40

d'un autre côté, ce qui suit ne fonctionne pas, et donne la même erreur que ci-dessus:

>> x(-0.6:2)
>> x(-0.5:2)

Le comportement observé peut être résumés comme suit:

  • l'arrondi interne donne un coup de pied quand un index du côlon est utilisé. Un index de côlon est un expression de la forme a:b ou a:b:c. Aucun arrondi n'a lieu lorsque le tableau d'indexation est un tableau standard, tel que [a b c] ou encore [a:b] ou [a:b:c].
  • L'arrondissement est fait à la entier le plus proche, sauf que les numéros entre -0.5 et 0.5 cas particulier: ils sont arrondis à l' 1 au lieu de 0. Bien sûr, si l'entier résultant de l'arrondi est négatif, une erreur produire.

un comportement similaire est observé dans les versions récentes de Octave sauf que:

  • apparemment, l'arrondissement normal à l'entier le plus proche est fait, sans traiter les nombres entre -0.5 et 0.5 comme cas particulier; et donc ceux-ci donnent une erreur:

    >> x(0.4:3)
    >> x(-0.4:3)
    
  • une erreur est émise lorsque la plage non-entière contient une seule valeur:x(2.4:4) fonctionne, mais x(3.4:4) Non (Bien sûr, x([2.4 3.4]) et x(3.4) ne fonctionne pas non plus).

Autre que cela, les résultats sont les mêmes que dans Matlab, et un avertissement est également émis (Non-intervalle entier utilisé comme index).

les avertissements et le fait Qu'Octave fonctionne de la même manière que Matlab suggèrent que C'est but comportement. Est-il documentée quelque part? Quelqu'un peut-il donner plus d'informations ou pour faire la lumière là-dessus?

29
demandé sur Luis Mendo 2016-11-07 01:31:46

1 réponses

observations supplémentaires:

  • x(1.2:3) devrait théoriquement être interprété comme:subsref(x, substruct('()',1.2:3)). Toutefois, comme indiqué dans la question," aucun arrondi n'a lieu lorsque le tableau d'indexation est un tableau standard", ce qui entraîne l'échec de la référence explicite. Ceci suggère qu'un mécanisme similaire à le court-circuit logique ou peut-être multithread partitionnement (où les variables intermédiaires sont "pas vraiment" créé").

  • l'Identificateur de l'avertissement émis est MATLAB:colon:nonIntegerIndex.

Théories:

  • peut-être Existe-t-il des versions surchargées de la référence subscriptée où il y a une première étape pour détecter si les indices eux-mêmes sont des entiers ou non. Dans le cas contraire, MATLAB "redirige" ceci vers une autre famille de classes (exemple).

officielle commentaires:

  • c'est Ce que Steve Eddins of TMW avait à dire sur le sujet:

    ... dans les premiers temps, les responsables de la mise en œuvre de MATLAB avaient tendance à être aussi permissifs que possible en ce qui concerne la validation des entrées. Avec le temps, nous avons réalisé que cette philosophie n'était pas toujours la meilleure pour les utilisateurs, et nous avons commencé à rendre certaines règles linguistiques plus strictes et plus régulières. Un exemple était l'introduction de messages d'erreur sur les indices invalides. (non entières, nonpositive, etc.). Cependant, nous ne pouvions pas toujours serrer le comportement autant que nous avons aimé. Parfois, c'est parce que nous avons découvert que trop de code utilisateur exploitait le comportement original. C'est l'une des raisons pour lesquelles vous continuez à voir ce genre de variation de comportement dans certains endroits. ... Je conseillerais aux utilisateurs de n'utiliser que des indices à valeur entière. Les utilisateurs peuvent explicitement appeler rond ou plancher ou quoi que ce soit pour convertir la sortie de l'opérateur de côlon pour être une valeur entière.

4
répondu Dev-iL 2017-05-23 12:09:32