Взаимодействие значений между двумя векторами в Matlab - PullRequest
1 голос
/ 29 марта 2011

У меня есть два вектора o и c равной длины:

o = [-1 -1 -1  0 0 0 1 1 0  0];
c = [-1 -1 -1 -1 0 1 1 1 0 -1];

o представляет сигналы открытия (neg или pos), а c представляет сигналы закрытия, принимая сигнал открытияпредшествовал ему с противоположным знаком.Только один сигнал может быть активным одновременно, поэтому последовательные сигналы должны игнорироваться.В двух вышеупомянутых векторах мой первый сигнал будет в o(1), а соответствующий ему сигнал закрытия будет найден в c(6).Это также означает, что сигналы открытия в o(2) и o(3) должны игнорироваться, и мой следующий сигнал открытия находится в o(7) с соответствующим закрытием в c(10), что приводит к пустому сигналу в o(8)

Я пытаюсь найти векторизованное решение для определения правильной последовательности или индексов открытых / закрытых сигналов, чтобы произвести что-то вроде следующего примера решения:

o = [-1 0 0 0 0 0 1 0 0  0];
c = [ 0 0 0 0 0 1 0 0 0 -1];

Я, очевидно, могу решить эту проблемуциклически просматривая каждый элемент в цикле for, но поскольку мой набор данных может содержать до миллионов элементов, и я считаю, что циклы в Matlab могут быть довольно «дорогими», я был бы очень признателен, если у кого-то есть решение моей проблемы, которое является более матричным.ориентированный или через arrayfun или что-то подобное, что может сделать код более эффективным?

Ответы [ 2 ]

1 голос
/ 29 марта 2011

Вы можете использовать diff вместе с некоторыми логическими операциями, чтобы получить ответ.

o=[-1,-1,-1,0,0,0,1,1,0,0];
oFinal=abs(diff([0,o])).*o;

oFinal=

    -1     0     0     0     0     0     1     0     0     0

Хитрость в том, что выходные данные diff и ваш исходный вектор o оба имеют не-нулевое значение с тем же индексом только для первого вхождения значения в o (т. е. первого вхождения в цепочке).Итак, умножив его поэлементно на o, вы получите свой ответ.abs должен гарантировать, что изменение знака не произойдет из-за вывода diff.

Подход аналогичен для c, и я оставлю это для вас, чтобы попробовать:)

0 голосов
/ 29 марта 2011

Обычно зацикливание обходится не дороже, чем выполнение какой-либо другой операции, которая просто скрывает цикл за другой функцией (например, arrayfun).Из вашего текста просто звучит, что вы просто выбрали неправильный алгоритм.Ваша проблема звучит очень линейно, то есть O (n), но вы пишете о цикле в цикле, что означает O (n ^ 2).С миллионами элементов квадратичная среда выполнения не так хороша.

Алгоритм, который вы хотите, выглядит примерно так:

open = 0;

for i=1:length(o)
  if (open == 0) 
     open=o(i)
  else 
     o(i) = 0;
  end
  if (c(i) ~= -open) 
     c(i) = 0;
  else 
     open = 0;
  end
end

Возможно, ему нужно немного finetunig, поскольку вы не описали подробно, например, каков порядок сигналов c и o (например, еслиодин и тот же индекс открывается и закрывается сначала обработанным открытием или закрытым, мой пример кода предполагает открытие), или порядок сигналов всегда в порядке, или если должна быть некоторая обработка ошибок - но я предполагаю, что вы понялиодин цикл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...