Индексы нижнего индекса должны быть либо действительными положительными целыми числами, либо логическими, обобщенным решением

40

Часто возникает ошибка:

Индексы индексов должны быть либо натуральными целыми числами, либо логическими

Я нашел много вопросов об этом, но не один с действительно общим ответом. Поэтому я хотел бы иметь общее решение для решения этой проблемы.

  • 0
    Я предлагаю расширить этот контроль качества с двумя другими очень тесно связанными ошибками. Рассмотрим: >> mean=1:4; >> mean(12) Index exceeds matrix dimensions. >> mean(12); Attempted to access mean(12); index out of bounds because numel(mean)=4. Во-первых, это ошибка «Индекс превышает размеры матрицы», когда случайное именование переменной является встроенной, а затем пытается использовать встроенную функцию. Второй - причудливый вариант, который просто предоставляет больше деталей об этой же ошибке.
  • 0
    @chappjc Хотя ошибки связаны, главная цель этого поста - помочь людям, которые получают это конкретное сообщение об ошибке. Конечно, может быть хорошей идеей найти / создать хороший справочный вопрос и ответ для каждого распространенного сообщения об ошибке.
Показать ещё 1 комментарий
Теги:
debugging

3 ответа

58
Лучший ответ

Индексы индексов должны быть либо натуральными натуральными, либо логическими

Почти во всех случаях эта ошибка вызвана одной из двух причин. К счастью, это легко проверить.

Прежде всего убедитесь, что вы находитесь на линии, где происходит ошибка, этого обычно можно достичь, используя dbstop if error перед запуском вашей функции или script. Теперь мы можем проверить первую проблему:

1. Где-то недопустимый индекс используется для доступа к переменной

Найти каждую переменную и посмотреть, как они индексируются. Индексируемая переменная обычно находится в одной из следующих форм:

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

Теперь просто взгляните на материал между скобками и выберите каждый индекс. Затем нажмите f9, чтобы оценить результат и проверить, является ли оно реальным положительным целым или логическим. Визуальный осмотр обычно достаточен (помните, что допустимые значения находятся в true, false или 1,2,3,... НО НО 0), но для большой матрицы вы можете использовать такие вещи, как isequal(index, round(index)), или более точно isequal(x, max(1,round(abs(x)))) для проверки действительных натуральных чисел. Чтобы проверить класс, вы можете использовать class(index), который должен возвращать "логический", если все значения "true" или "false".

Обязательно проверьте каждый индекс, даже те, которые выглядят необычно, как показано в примере ниже. Если все индексы проверяются, вы, вероятно, сталкиваетесь со второй проблемой:

2. Имя функции было омрачено пользовательской переменной

Функции MATLAB часто имеют очень интуитивные имена. Это удобно, но иногда приводит к случайным перегрузкам (встроенным) функциям, т.е. Созданию переменной с тем же именем, что и функция, например, вы можете пойти max = 9, а для остальных из вас script/функция Matlab рассмотрит max вместо переменной max вместо переменной max вы получите эту ошибку, если вы попробуете что-то вроде max([1 8 0 3 7]), потому что вместо возврата максимального значения этого вектора Matlab теперь предполагает, что вы пытаетесь индексировать переменную max и 0 - недопустимый индекс.

Чтобы проверить, какие переменные у вас есть, вы можете посмотреть рабочее пространство. Однако, если вы ищете систематический подход, вы можете:

Для каждой буквы или слова, за которыми следуют скобки (), и не подтверждено, что на шаге 1 есть соответствующие индексы. Проверьте, является ли это фактически переменной. Это легко сделать, используя which.


Примеры

Простое появление недопустимого индекса

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

Здесь мы будем оценивать b/c и находим, что это не очень округленное число.

Сложное появление недопустимого индекса

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

Я рекомендую работать наизнанку. Поэтому сначала оцените индексированную самую внутреннюю переменную: d. Оказывается, что cell2mat({b}):c, прекрасно оценивает целые числа. Затем оцените b+mean(d(cell2mat({b}):c)) и найдите, что у нас нет целочисленного или логического индекса в a.

Здесь мы будем оценивать b/c и находим, что это не очень округленное число.

Перегрузка функции

which mean 
% some directory\filename.m

Вы должны увидеть что-то подобное, чтобы фактически подтвердить, что что-то является функцией.

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

Здесь мы видим, что mean случайно присвоено. Теперь получим:

which mean
% mean is a variable.
  • 1
    Отличный ответ. Возможно, вы захотите добавить конкретную оговорку для использования i и j качестве переменных цикла, так как они уже являются мнимой единицей перед их назначением. (Это не для того, чтобы выступать против использования i и j качестве имен переменных, просто в качестве наблюдения, поскольку я часто вижу, что один из них является виновником этой ошибки.)
4

Ответы на этот вопрос до сих пор были сосредоточены на источниках этой ошибки, что здорово. Но важно понять мощную, но очень интуитивную функцию индексирования матриц в Matlab. Следовательно, как работает индексация и что является допустимым индексом, во избежание этой ошибки, в первую очередь, используя допустимые индексы.

В своей основе, учитывая массив A длины n, есть два способа его индексирования.

  • Линейное индексирование: с подмножеством целых чисел от 1 : n (допускаются дубликаты). 0 не допускается, так как массивы Matlab основаны на 1, если вы не используете метод ниже. Для многомерных массивов несколько индексов внутри преобразуются в линейный индекс, хотя и эффективным и прозрачным образом.
  • Логическая индексация: при использовании массива n-length из 0s и 1s выберите те элементы, где индексирование истинно. В этом случае уникальный (индекс) должен иметь только 0 и 1.

Итак, допустимый массив индексирования в другой массив с n числом элементов ca be:

  • полностью логичен одного размера или
  • линейный с подмножествами целых чисел от 1: n

Помня об этом, неверная ошибка индексирования возникает при смешивании двух типов индексирования: один или несколько нулей встречаются в линейном индексирующем массиве, или вы смешиваете 0 и 1 с чем-либо, кроме 0 и 1 с:)

Есть много материалов онлайн, чтобы узнать это, включая этот: http://www.mathworks.com/company/newsletters/articles/matrix-indexing-in-matlab.html

  • 0
    В целом, это хорошее объяснение, и я не хочу вас расстраивать, но кажется, что часть, где вы на самом деле отвечаете на конкретный вопрос, уже рассмотрена. Таким образом, я думаю, что это должен быть комментарий, а не ответ. (Я не отмечал это, поскольку это слишком долго, чтобы быть переданным комментарию, но имейте это в виду для будущих сообщений).
  • 0
    Спасибо Деннис. Я подумал о том, стоит ли мне тратить свое время (что может потратить время других людей, если это не добавляет много), и решил, что это улучшит способности людей в будущем. если есть, возможно, вы можете переместить его в мета-место для учебников / советов по matlab, так как это объяснение лежит в основе важной функции.
4

В Matlab (и большинстве других языков программирования) знак умножения всегда должен быть записан. Хотя в вашем математическом классе вы, вероятно, узнали, что вместо a*(a+a) вы можете написать write a(a+a), это не то же самое в matlab. Первый - это вызов индексирования или функции, а второй - умножение.

>> a=0

a =

     0

>> a*(a+a)

ans =

     0

>> a(a+a)
Subscript indices must either be real
positive integers or logicals.
  • 0
    Хотя этот случай неявно описан в пункте 1 моего ответа, мне нравится дополнительный пример того, как это может произойти. Добавление комментария, чтобы помочь людям, которые ищут индексы Subscript, должно быть либо действительными положительными целыми числами, либо логикой при выполнении умножения .

Ещё вопросы

Сообщество Overcoder
Наверх
Меню