проверить чередование максимумов минимумов в матлабе

Я написал алгоритм, который находит локальные максимумы и минимумы в сигнале.

[id_max, id_min] = find_max_min(signal);

Теперь я хотел бы проверить: соблюдается ли чередование максимумов и минимумов

i.e. id_max(1)<id_min(1)<id_max(2)<id_min(2)<... 
we could start with a minimum..this is not known

Предположим, что:

 id_max = [1 3 5 7 10 14 20];

 id_min = [2 4 6 8 16 19];

Я хотел бы иметь 2 вектора missing_max missing_min с указанием местоположения недостающих максимумов и минимумов.

Отсутствующий максимум (минимум) возникает, когда между двумя последовательными минимумами (максимумами) в id_min (id_max) нет максимума (минимума).

В этом примере отсутствует максимум в 7-й позиции id_max, потому что в id_min есть два последовательных значения (16 19) без максимума между ними.

Тогда у нас есть

missing_max = [7]

missing_min = [5]

поскольку

id_max = [1 3 5 7 10 14 X 20];

id_min = [2 4 6 8 X 16 19]; (с помощью X я отметил пропущенные значения)

Если чередование правильное, векторы должны быть пустыми. Можете ли вы предложить эффективный способ сделать это без циклов?

заранее спасибо


person gabboshow    schedule 25.06.2014    source источник
comment
Гарантировано ли, что идентификаторы имеют целочисленные значения?   -  person    schedule 25.06.2014
comment
да они целые   -  person gabboshow    schedule 25.06.2014
comment
Скоро дам ответ. Однако: между 4-й = 8 и 5-й = 16 позициями в минимумах есть максимумы, 10 и 14. missing_min должно быть [6], согласны?   -  person    schedule 25.06.2014
comment
да, я согласен, я отредактировал вопрос   -  person gabboshow    schedule 25.06.2014
comment
извините, на самом деле нет, я не согласен, потому что в 5-й позиции отсутствует минимум, потому что в 5-й и 6-й позициях есть 2 последовательных максимума.   -  person gabboshow    schedule 25.06.2014
comment
О, это немного меняет проблему... во-первых, вам нужно гарантировать, что векторы id отсортированы, иначе позиция ничего бы не значила. Вы можете это гарантировать?   -  person    schedule 25.06.2014
comment
да. Извините, если я был не ясен   -  person gabboshow    schedule 25.06.2014
comment
Хорошо, просто чтобы уточнить определение, я хотел бы иметь еще один пример: предположим, id_min=[2 4 6 8 10] и id_max=[12 14]. Что будет missing_max и missing_mim   -  person    schedule 25.06.2014
comment
это должно быть missin_min = [6] иmissin_max = [1 2 3 4]   -  person gabboshow    schedule 25.06.2014
comment
Но в id_max нет 3-й и 4-й позиции, а в id_min нет 6-й позиции, поэтому значение, отсутствующее между k-1 и k позициями, не работает. Не могли бы вы рассказать, как вы пришли к этим ценностям?   -  person    schedule 25.06.2014
comment
Я сортирую максимумы и минимумы в уникальном массиве, принимая во внимание, что максимум должен быть между двумя минимумами и наоборот. так что это будет [2,?,4,?,6,?,8,?,10,12,?,14] в этом случае нечетные позиции являются минимумами (мы начинаем с минимума), а четные позиции максимумы. Я разделил на 2, чтобы получить индексы.   -  person gabboshow    schedule 25.06.2014
comment
Ну вот. Вы только что назвали алгоритм, который искали. :-)   -  person    schedule 25.06.2014
comment
ммм, не уверен, что смогу это реализовать... потому что не знаю, какой длины должен быть этот отсортированный вектор... на бумаге я могу добавить вопросительные знаки там, где считаю это необходимым...   -  person gabboshow    schedule 25.06.2014
comment
Новый код. Не так сильно отличается от первоначального... но все же. Как я уже сказал в посте, в сценарий встроен небольшой тизер: вы либо исправляете это, либо пишете действительно хорошее, хорошо объясненное определение missing_max и missing_in (потом я это исправлю). Что ты говоришь? :-)   -  person    schedule 25.06.2014
comment
Я говорю, что я отредактировал вопрос и сделал все возможное :)   -  person gabboshow    schedule 25.06.2014
comment
Исправлен код и добавлено объяснение ошибки. Надеюсь, он будет хорошо работать для того, что вам нужно.   -  person    schedule 25.06.2014


Ответы (1)


Вот скрипт, который вы можете адаптировать к функции, если хотите:

    id_max = [1 3 5 7 10 14 20];
    id_min = [2 4 6 8 16 19];

    % Group all values, codify extremity (1-max, 0-min), and position
    id_all   = [          id_max,              id_min  ];
    code_all = [ones(size(id_max)), zeros(size(id_min))];
    posn_all = [  1:numel(id_max),     1:numel(id_min) ];

    % Reshuffle the codes and positions according to sorted IDs of min/max
    [~, ix]  = sort(id_all);
    code_all = code_all(ix);
    posn_all = posn_all(ix);

    % Find adjacent IDs that have the same code, i.e. code diff = 0
    code_diff = (diff(code_all)==0);

    % Get the indices of same-code neighbors, and their original positions
    ix_missing_min = find([code_diff,false] & (code_all==1));
    ix_missing_max = find([code_diff,false] & (code_all==0));

    missing_min    = posn_all(ix_missing_min+1);
    missing_max    = posn_all(ix_missing_max+1);

Предупреждения об идентификаторах:

  1. Убедитесь, что ваши id_min и id_max являются строками (даже если они пусты);
  2. Убедитесь, что хотя бы один из них не пуст;
  3. Хотя их не нужно сортировать, их значения должны быть уникальными (в пределах идентификаторов и между ними).

Позднее редактирование:

Новая версия кода, основанная на новых пояснениях к определению:

    id_max = [1 3 5 7 10 14 20];
    id_min = [2 4 6 8 16 19];
    %id_max = [12 14]
    %id_min = [2 4 6 8 10];

    id_min_ext = [-Inf, id_min];
    id_max_ext = [-Inf, id_max];

    % Group all values, and codify their extremity (1-max, 0-min), and position
    id_all   = [          id_max_ext,              id_min_ext  ];
    code_all = [ones(size(id_max_ext)), zeros(size(id_min_ext))];
    posn_all = [  0:numel(id_max),         0:numel(id_min)     ];

    % Reshuffle the codes and position according to sorted positions of min/max
    [~, ix] = sort(id_all);
    code_all = code_all(ix);
    posn_all = posn_all(ix);

    % Find adjacent IDs that have the same code, i.e. code diff = 0
    code_diff = (diff(code_all)==0);

    % Get the indices of same-code neighbours, and their original positions
    ix_missing_min = find([code_diff,false] & (code_all==1));
    ix_missing_max = find([code_diff,false] & (code_all==0));

    missing_min    = unique(posn_all(ix_missing_min-1))+1;
    missing_max    = unique(posn_all(ix_missing_max-1))+1;

Однако код содержит незаметную ошибку. Ошибка будет удалена либо человеком, задавшим вопрос, либо мной после того, как он/она улучшит вопрос таким образом, чтобы было действительно ясно, о чем он спрашивает. :-) В связи с тем, что у нас 2 виртуальных экстремума (один максимальный и один минимальный, при ID = ), возможно, что первый отсутствующий экстремум будет отмечен дважды: один раз в и один раз в первом элементе ID список. unique() позаботится об этом (хотя это слишком много вызова функции, чтобы проверить, имеют ли первые 2 элемента массива одинаковое значение)

person Community    schedule 25.06.2014
comment
спасибо за ответ, но это не то, что я искал... я отредактировал свой вопрос... раньше я немного запутался.. - person gabboshow; 25.06.2014