我需要取一个向量的子集的最大值,然后通过向量移位。例如列向量
a=[1;2;3;4;5;6;7]
如何处理max(a(1:3))
,max(a(2:4))
,...,max(a(5:end))
并将所有输出放在另一个向量中?我可以使用for循环轻松完成这个操作但是我正在寻找一种优雅的方法,使用MATLAB中的矩阵运算,最好是在一行代码中(尽管我意识到MATLAB中的矩阵运算可能会这样做)使用for循环实现)。
谢谢!
答案 0 :(得分:2)
假设你的移位和窗口长度是恒定的(在你的情况下分别为1和3),你可以使用nlfilter来定义向量上的一般滑动窗口操作:
a = [1:7];
fun = @(x) max(x(:));
b = nlfilter(a, [1 4], fun);
答案 1 :(得分:1)
对于您提供的示例:
b = max([a(1:end-2) a(2:end-1) a(3:end)], [], 2)
我觉得还有一个更优雅,更通用的accumarray
解决方案,虽然我现在没有时间召唤一个人:)
答案 2 :(得分:1)
这是我的尝试。首先,定义“窗口”长度(在您的情况下为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
当然有效,速度提高了两倍以上。
答案 3 :(得分:0)
如果您有信号处理工具箱,则可以使用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
答案 4 :(得分:-1)
感谢所有帮助。这给了我一些想法,特别是使用nlfitler的建议。事实证明,nlfitler调用im2col并且取这个最大值对我有用。特别是因为所呈现的样本向量是包含随机变量的实数向量的简化,因此存在的bsxfun选项不起作用。
max(im2col(a,[3 1],'sliding'))