我需要取向量子集的最大值,然后在向量中移动。例如列向量
a=[1;2;3;4;5;6;7]
如何获取max(a(1:3))
, max(a(2:4))
, ...max(a(5:end))
并将所有输出放在另一个向量中?我可以使用 for 循环轻松地做到这一点,但是我正在寻找一种优雅的方式来使用 MATLAB 中的矩阵运算,最好是在一行代码中(尽管我意识到 MATLAB 中的矩阵运算可能会这样做正在使用 for 循环来实现)。
谢谢!
我需要取向量子集的最大值,然后在向量中移动。例如列向量
a=[1;2;3;4;5;6;7]
如何获取max(a(1:3))
, max(a(2:4))
, ...max(a(5:end))
并将所有输出放在另一个向量中?我可以使用 for 循环轻松地做到这一点,但是我正在寻找一种优雅的方式来使用 MATLAB 中的矩阵运算,最好是在一行代码中(尽管我意识到 MATLAB 中的矩阵运算可能会这样做正在使用 for 循环来实现)。
谢谢!
假设您的移位和窗口长度是恒定的(在您的情况下分别为 1 和 3),您可以使用nlfilter在向量上定义一般的滑动窗口操作:
a = [1:7];
fun = @(x) max(x(:));
b = nlfilter(a, [1 4], fun);
对于您提供的示例:
b = max([a(1:end-2) a(2:end-1) a(3:end)], [], 2)
我觉得还有一个更优雅、更通用的accumarray
解决方案,虽然我现在没有时间想出一个:)
这是我的尝试。首先,定义“窗口”长度(在您的情况下为 3)。接下来,用于为每个窗口bsxfun
的向量创建索引。a
最后一步是一个简单的max
函数调用:
flen = 3;
idx = bsxfun(@plus, [0:flen-1]', 1:numel(a)-flen+1);
max(a(idx))
它是通用的,即您可以更改窗口大小。
它是基本的 matlab,应该比 快nlfilter
,虽然我现在无法验证它。
编辑这里是上述bsxfun
解决方案和建议的简要性能比较im2col
:
a = rand(10^7,1);
tic;
idx = bsxfun(@plus, [0:2]', 1:numel(a)-2);
m1 = max(a(idx));
toc
tic;
m2 = max(im2col(a,[3 1],'sliding'));
toc;
isequal(m1, m2)
Elapsed time is 0.839869 seconds.
Elapsed time is 1.797665 seconds.
ans =
1
bsxfun
当然可以,而且速度快两倍多。
如果您有信号处理工具箱,则可以使用该buffer
功能。它接受一个向量并生成一个矩阵,其中每一列都包含滑动窗口内的向量值。
在你的情况下:
>> a = (1:7)';
>> buffer(a,3,2,'nodelay')
ans =
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
然后,只需应用 MATLAB 的max
函数来计算每列的最大值。总之,只需一行代码,
>> max(buffer(a,3,2,'nodelay'))
ans =
3 4 5 6 7
感谢所有的帮助。这给了我一些想法,尤其是使用 nlfitler 的建议。事实证明,nlfitler 调用 im2col 并取其最大值对我有用。特别是因为提供的样本向量是包含随机变量的实向量的简化,因此存在的 bsxfun 选项将不起作用。
最大值(im2col(a,[3 1],'滑动'))