Ниже приведено решение с использованием цикла.Он также включает возможность определения размера шага.
% Input.
x = round(rand(20, 1) * 100)
% Window size.
ws = 5;
% Step size.
ss = 1;
% Number of elements.
nx = numel(x);
% Number of result elements.
ny = numel(1:ss:(nx - ws + 1));
% Initialize output.
y = zeros(ny, 1);
% Calculate output.
jj = 1;
for ii = 1:ss:(nx - ws + 1)
ww = x(ii:(ii + ws - 1));
[~, yLoop(jj)] = min(ww);
yLoop(jj) = yLoop(jj) + ii - 1;
jj = jj + 1;
end
% Output.
y
Индексы минимумов, хранящиеся в y
, относятся к исходному вводу x
.
Вывод для ws = 5
и ss = 1
:
x =
88
74
96
31
6
67
98
92
69
49
12
28
43
87
68
49
20
98
83
62
y =
5
5
5
5
5
10
11
11
11
11
11
12
17
17
17
17
EDIT
Я добавил версию с использованием индексации, которая намного быстрее для больших входных данных.
% Input.
x = round(rand(20000, 1) * 100);
% Window size.
ws = 5;
% Step size.
ss = 1;
% Number of elements.
nx = numel(x);
% --- Solution using loop --- %
% Number of result elements.
ny = numel(1:ss:(nx - ws + 1));
% Initialize output (loop).
yLoop = zeros(ny, 1);
tic
% Calculate output.
jj = 1;
for ii = 1:ss:(nx - ws + 1)
ww = x(ii:(ii + ws - 1));
[~, yLoop(jj)] = min(ww);
yLoop(jj) = yLoop(jj) + ii - 1;
jj = jj + 1;
end
tLoop = toc;
% Output (loop).
yLoop;
% --- Solution using indexing --- %
tic
% Calculate indices.
ind = 1:ss:(nx - ws + 1);
ind = repmat(ind, ws, 1) + ([0:(ws - 1)].' * ones(1, numel(ind)));
% Calculate output (indexing).
[~, yIndexing] = min(x(ind));
yIndexing = (yIndexing + (0:ss:(ss * (size(ind, 2) - 1)))).';
tIndexing = toc;
% Compare loop and indexing version.
fprintf("yLoop == yIndexing: %d\n", sum(yLoop == yIndexing) == ny);
fprintf("yLoop time: %f s\n", tLoop);
fprintf("yIndeing time: %f s\n", tIndexing);
Для n = 20000
, ws = 5
и ss = 1
, мы получаем следующие времена:
yLoop time: 0.672510 s
yIndeing time: 0.004466 s