¿Matlab acepta índices no enteros?


¡Por supuesto que no! ...O no? Vamos a hacer algunas pruebas.

Define x = [10 20 30 40 50]. Entonces cualquiera de las siguientes instrucciones, como se esperaba, da un error en Matlab (Los índices de subíndices deben ser enteros positivos reales o lógicos):

>> 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)

Sin Embargo, los valores no enteros se aceptan en colon índices. Todo lo siguiente funciona en versiones recientes de Matlab, aunque con una advertencia (Se requieren operandos enteros para el operador de dos puntos cuando se usa como 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

También funciona si la expresión de dos puntos incluye end:

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

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

Por otro lado, lo siguiente no funciona, y da el mismo error que el anterior:

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

El comportamiento observado puede ser resumido de la siguiente manera:

  • Algunos redondeo interno se activa cuando se usa un índice de puntos . Un índice de dos puntos es una expresión de la forma a:b o a:b:c. No se realiza redondeo cuando la matriz de indexación es un estándar array, como [a b c] o incluso [a:b] o [a:b:c].
  • El redondeo se hace al entero más cercano, excepto que los números entre -0.5 y 0.5 son especiales: se redondean a 1 en lugar de a 0. Por supuesto, si el entero resultante del redondeo es negativo se produce un error.

Comportamiento similar se ve en versiones recientes de Octave excepto que:

  • Aparentemente, el redondeo normal al entero más cercano se hace, sin tratar los números entre -0.5 y 0.5 como un caso especial; y así estos dan un error:

    >> x(0.4:3)
    >> x(-0.4:3)
    
  • Se emite un error cuando el rango no entero contiene un solo valor: x(2.4:4) funciona, pero x(3.4:4) no (por supuesto, x([2.4 3.4]) y x(3.4) tampoco funcionan).

Aparte de esto, los resultados son los mismos que en Matlab, y también se emite una advertencia ( Rango no entero utilizado como índice).

Las advertencias y el hecho de que Octave funciona de manera similar como Matlab sugiere que este es comportamiento previsto. ¿Está documentado en alguna parte? ¿Puede alguien dar más información o arrojar algo de luz sobre esto?

Author: Luis Mendo, 2016-11-07

1 answers

Observaciones adicionales:

  • x(1.2:3) teóricamente debe interpretarse como: subsref(x, substruct('()',1.2:3)). Sin embargo, como se mencionó en la pregunta, "No se realiza redondeo cuando la matriz de indexación es una matriz estándar", lo que hace que la referencia explícita de subíndices falle. Esto sugiere que un mecanismo similar a cortocircuito lógico o tal vez particionamiento multihilo (donde las variables intermedias "no son realmente creadas") toma lugar.

  • El identificador de la advertencia emitida es MATLAB:colon:nonIntegerIndex.

Teorías:

  • Tal vez existen versiones sobrecargadas de la referencia subíndice donde hay un paso inicial de detectar si los subíndices en sí son enteros o no. En caso de que no lo sean, MATLAB "redirige" esto a alguna otra familia de clases ( ejemplo).

Comentarios oficiales:

  • Esto es lo que Steve Eddins de TMW tuvo que decir sobre el tema:

    ... en sus primeros días, los implementadores de MATLAB tenían una tendencia a ser lo más permisivos posible con respecto a la validación de entrada. Con el tiempo, nos dimos cuenta de que esta filosofía no siempre era la mejor para los usuarios, y empezamos a hacer algunas de las reglas del idioma más estrictas y más regulares. Un ejemplo fue la introducción de los mensajes de error sobre inválida índices (no entera, valor no positivo, etc.). Sin embargo, no siempre pudimos endurecer el comportamiento tanto como como. A veces eso fue porque descubrimos que demasiado código de usuario estaba explotando el comportamiento original. Esa es una de las razones por las que continúas viendo este tipo de variación de comportamiento en algunos lugares. ... Yo aconsejaría a los usuarios que solo utilicen índices de valor entero. Los usuarios pueden llamar explícitamente a round o floor o lo que sea para convertir la salida del operador de dos puntos a un valor entero.

 4
Author: Dev-iL,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:09:32