простой скользящий оконный фильтр в Matlab - PullRequest
3 голосов
/ 02 ноября 2011

У меня нет пакета для nlfilter, и я не совсем следовал этому примеру .

У меня действительно простая функция fun, и я хочу применитьэто к движущемуся окну массива.Массив Nx1, и я хочу посмотреть, скажем, на интервалы k длины.Так что для N=10 и k=3 и fun = @(x) min(x); я бы получил

A = [13 14 2 14 10 3 5 9 15 8];

filter(A,k,fun) = [2 2 2 3 3 3 5 8];

Здесь я хочу посмотреть только на индексы 1,2,3, затем 2,3,4, потом ... потом 8, 9,10, итоговая последовательность - длина 7. Я могу сделать это легко с помощью цикла for, но я не знаю, как его векторизовать для Matlab.Помогите, пожалуйста.Спасибо.

Ответы [ 2 ]

6 голосов
/ 02 ноября 2011

Вот один очень простой и быстрый способ сделать это:

>> min([A(1:(end-2)); A(2:(end-1)); A(3:end)], [], 1)

ans =

     2     2     2     3     3     3     5     8

РЕДАКТИРОВАТЬ: так как вы хотите полную функцию ...

function running_min = running_min(x, k)

xrep = repmat(x, 1, k);
xrep = reshape([xrep zeros(1, k)], length(x)+1, k);
running_min = min(xrep, [], 2)';
running_min = running_min(1:end-k);
4 голосов
/ 09 ноября 2011

Упомянутая вами запись дала общее решение для построения раздвижных окон (вы можете контролировать: перекрытие или различение, шаг скольжения, количество перекрытий, размер окна)

В вашем случае это намного проще и может быть легко выполнено с помощью функции HANKEL :

x = [13 14 2 14 10 3 5 9 15 8];
idx = hankel(1:3, 3:length(x))
min( x(idx) )

Если вы хотите создать повторно используемое решение:

function y = myFilter(x,k,fcn)
    idx = hankel(1:k, k:length(x));
    y = cellfun(fcn, num2cell(x(idx),1));
end

который мы используем как:

x = [13 14 2 14 10 3 5 9 15 8];
y = myFilter(x, 3, @(x)min(x))

Примечание. Я использую CELLFUN, если fcn не может работать с измерениями в векторизованном виде ...

...