Ошибка при использовании sub2ind (строка 52) Вне диапазона нижнего индекса Matlab

Я использовал один и тот же код для двух разных входных матриц. В обоих случаях я буду называть это "входной матрицей A"

Первый корпус - 7000X4

Второй корпус - 29500X12

Мне нужно разделить выбранный столбец в окнах, а затем для каждого окна мне нужно вычислить стандартное значение и сохранить значение внутри матрицы std_vals

Я позаботился об изменении значения моих входных переменных.

В первом случае моей целью было проанализировать 4-й столбец, во втором случае — проанализировать 12-й столбец.

В первом случае код сработал

Во втором случае код вернул мне сообщение об ошибке

Я попытался проанализировать все шаги в коде, но не нашел ошибки.

Не могли бы вы помочь мне лучше понять?

column_length=size(A,1);
Amod= mod(column_length,100);
if Amod~=0
    A=A(1:(size(A,1)-Amod),:);
    end
newlenght=size(A);

%selected column vector to analyze
columnselected=4;
%window dimension
window_size=200; 

%overlap between two windows
overlap=0;

%increment needed
step=window_size - overlap; 

%std threshold 
soglia=2; 
std_vals= NaN(size(A,1),1); 
devstd=std(A(:,4));

stdInds=bsxfun(@plus,1:step:(size(A,1)-overlap),(0:(window_size-1)).'); 

%In the first case size(stdInds)=200X35
%In the second case size(stdInds)=200X148
%In the first case size(repmat(columnselected,size(stdInds))=   200X35
%In the second case size(repmat(columnselected,size(stdInds))=  200X148
%In the first case size(A)=7000X4
%In the second case size(A)=29500X12
  std_vals=std(A(sub2ind(size(A),stdInds,repmat(columnselected,size(stdInds)))));

highStdWindows=find(std_vals>soglia);

Я самоучка. Чтобы лучше понять свою ошибку, я сначала переписываю код на листе бумаги, затем анализирую каждый шаг и изучаю вывод. У меня ушло более 4 часов.

Я также пытался поставить во втором случае вектор 7000X12, но код выдал мне ту же ошибку.

Я думаю, что мой метод не очень эффективен. введите здесь описание изображения


person Andrea Ciufo    schedule 07.07.2017    source источник
comment
Я не устранил неполадки, почему вы получаете ошибки, но я предоставил другое решение ниже для тривиального случая нулевого перекрытия между окнами.   -  person b3.    schedule 08.07.2017
comment
@b3. в наборе данных есть какая-то странная ошибка или аномалия, я буду углубляться, потому что я пробовал с 102047X12, и он работает без проблем.   -  person Andrea Ciufo    schedule 08.07.2017


Ответы (2)


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

Вот теория о том, что происходит, хотя она не объясняет всего, о чем вы сообщили (она предполагает, что массив 7000x12 должен был работать):

Я думаю, проблема здесь в том, что первая часть вашего кода обрезает ввод, поэтому его высота кратна 100. Однако размер вашего окна равен 200, и эти числа должны были быть одинаковыми (для перекрытия 0). Это связано с тем, что вы вычисляете начальные точки ваших окон с помощью 1:step:(size(A,1)-overlap) = 1:200:size(A,1), что дает окончательное окно, которое не помещается в A, если только size(A,1) не кратно 200.

Учитывая размеры массива, которые вы пробовали:

  • 7000x4: 7000 кратно 200, так что это работает
  • 29500x12: 29500 не кратно 200, поэтому это не работает (последний элемент 1:200:29500 равен 29401, поэтому последнее окно равно 29401:29600)
  • 102047x12: 102047 усекается до 102000, что кратно 200, так что это работает
  • 7000x12: это должно работать так же, как 7000x4, что не соответствует тому, что вы видели!
person Mike Dinsdale    schedule 08.07.2017

Поскольку ваше перекрытие для окон равно нулю, приведенный ниже код должен работать для любого входного массива A. Измените переменные COLUMN_INDEX и WINDOW_SIZE на желаемый размер столбца и окна.

Идея состоит в том, чтобы изменить форму желаемого столбца WINDOW_SIZE x N. Затем просто вызовите функцию std, которая работает со столбцами этого измененного множество.

COLUMN_INDEX = 4;
WINDOW_SIZE  = 200;

windowCount = floor( size( A, 1 ) / WINDOW_SIZE );
windowedColumn = reshape( A(1:WINDOW_SIZE*windowCount,COLUMN_INDEX), WINDOW_SIZE, windowCount );
stdVals = std( windowedColumn );
person b3.    schedule 07.07.2017