Los índices de subíndice deben ser números enteros positivos reales o lógicos, solución genérica

El siguiente error ocurre con bastante frecuencia:

Los índices de subíndices deben ser números enteros positivos reales o lógicos

He encontrado muchas preguntas sobre esto, pero ninguna con una respuesta realmente genérica. Por lo tanto, me gustaría tener la solución general para enfrentar este problema.

Los índices de subíndices deben ser números enteros positivos reales o lógicos

En casi todos los casos, este error es causado por una de dos razones. Afortunadamente, hay un cheque fácil para esto.

En primer lugar, asegúrese de estar en la línea donde se produce el error, esto generalmente se puede lograr mediante el uso de dbstop if error antes de ejecutar su función o secuencia de comandos. Ahora podemos verificar el primer problema:

1. En algún lugar, se utiliza un índice no válido para acceder a una variable

Encuentre todas las variables y vea cómo se indexan. Una variable que se indexa suele estar en una de estas formas:

 variableName(index,index) variableName{index,index} variableName{indices}(indices) 

Ahora simplemente mira las cosas entre los corchetes, y selecciona cada índice. Luego f9 para evaluar el resultado y verificar si es un entero positivo real o lógico. La inspección visual suele ser suficiente (recuerde que los valores aceptables son verdaderos, falsos o 1,2,3, … PERO NO 0 ), pero para una matriz grande puede usar cosas como isequal(index, round(index)) , o más exactamente isequal(x, max(1,round(abs(x)))) para buscar enteros reales positivos. Para verificar la clase puede usar class(index) que debería devolver ‘logical’ si los valores son todos ‘true’ o ‘false’.

Asegúrese de verificar todos los índices, incluso los que parecen inusuales, como se muestra en el siguiente ejemplo. Si revisan todos los índices, probablemente se enfrentan al segundo problema:

2. Un nombre de función ha sido eclipsado por una variable definida por el usuario

Las funciones de MATLAB a menudo tienen nombres muy intuitivos. Esto es conveniente, pero a veces da como resultado funciones de sobrecarga (incorporadas) accidentalmente, es decir, crear una variable con el mismo nombre que una función, por ejemplo, puedes ir a max = 9 y para el rest de tu script / función Matlab considerará que max es un variable en lugar de la función max por lo que obtendrá este error si prueba algo como max([1 8 0 3 7]) porque en lugar de devolver el valor máximo de ese vector, Matlab ahora supone que está intentando indexar la variable max y 0 es un índice inválido.

Para verificar qué variables tiene, puede mirar el espacio de trabajo. Sin embargo, si está buscando un enfoque sistemático aquí hay uno:

Para cada letra o palabra que es seguida por corchetes () y no se ha confirmado que tenga índices adecuados en el paso 1. Verifique si realmente es una variable. Esto se puede hacer fácilmente mediante el which .


Ejemplos

Ocurrencia simple de índice inválido

 a = 1; b = 2; c = 3; a(b/c) 

Aquí evaluaremos b/c y descubriremos que no es un número muy redondeado.

Aparición complicada de índice no válido

 a = 1; b = 2; c = 3; d = 1:10; a(b+mean(d(cell2mat({b}):c))) 

Recomiendo trabajar de adentro hacia afuera. Entonces, primero evalúe la variable más interna que se indexa: d . Resulta que cell2mat({b}):c , muy bien evalúa a enteros. Luego evalúe b+mean(d(cell2mat({b}):c)) y descubra que no tenemos un entero o lógico como índice para a .

Aquí evaluaremos b/c y descubriremos que no es un número muy redondeado.

Sobrecargado una función

 which mean % some directory\filename.m 

Debería ver algo así para confirmar realmente que algo es una función.

 a = 1:4; b=0:0.1:1; mean(a) = 2.5; mean(b); 

Aquí vemos que la mean ha sido asignada accidentalmente. Ahora obtenemos:

 which mean % mean is a variable. 

En Matlab (y en la mayoría de los otros lenguajes de progtwigción) el signo de multiplicación siempre debe escribirse. Mientras que en tu clase de matemática probablemente aprendiste que puedes escribir escribir a(a+a) lugar de a*(a+a) , esto no es lo mismo en matlab. El primero es una llamada de indexación o función, mientras que el segundo es una multiplicación.

 >> a=0 a = 0 >> a*(a+a) ans = 0 >> a(a+a) Subscript indices must either be real positive integers or logicals. 

Las respuestas a esta pregunta hasta ahora se centraron en las fonts de este error, que es genial. Pero es importante comprender la poderosa pero muy intuitiva característica de la indexación matricial en Matlab. Por lo tanto, cómo funciona la indexación y qué es un índice válido ayudaría a evitar este error en primer lugar mediante el uso de índices válidos.

En su núcleo, dado un conjunto A de longitud n , hay dos formas de indexarlo.

  1. Indización lineal : con un subconjunto de enteros de 1 : n (duplicados permitidos). 0 no está permitido, ya que los arrays de Matlab están basados ​​en 1, a menos que use el método a continuación. Para matrices de mayor dimensión, múltiples subíndices se convierten internamente en un índice lineal , aunque de manera eficiente y transparente.
  2. Indización lógica : donde se usa una matriz de longitud n de 0 y 1, para elegir aquellos elementos donde la indexación es verdadera. En este caso, unique (index) debe tener solo 0 y 1.

Entonces, una matriz de indexación válida en otra matriz con n cantidad de elementos puede ser:

  1. completamente lógico del mismo tamaño, o
  2. lineal con subconjuntos de enteros de 1: n

Teniendo esto en cuenta, se produce un error de indexación no válido cuando se mezclan los dos tipos de indexación: uno o más ceros se producen en su matriz de indexación lineal, o se mezclan 0 y 1 con cualquier cosa que no sea 0 y 1 🙂

Hay toneladas de material en línea para aprender esto, incluido este: http://www.mathworks.com/company/newsletters/articles/matrix-indexing-in-matlab.html