如何在多个区间内找到最大值?

时间:2017-11-23 05:35:23

标签: matlab max octave

我有两个数组der_posder_neg,其中包含数组interpolated的索引。我希望获得区间中interpolated的最大值的所有索引:

der_pos(1):der_neg(1)
der_pos(2):der_neg(2)
etc...

例如:

interpolated = [1,5,3,2,7,10,8,14,4]
der_pos = [1,6]
der_neg = [4,9]

所以,我想获得指数:

[2,8]

由于:

  • der_pos(1):der_neg(1)1:4interpolated(1:4) = [1,5,3,2]的时间间隔内,最大值为5,其位于索引2

  • der_pos(2):der_neg(2)6:9interpolated(6:9) = [10,8,14,4]的时间间隔内,最大值为14,其位于索引8

我设法使用for循环:

interpolated = [1,5,3,2,7,10,8,14,4];

der_pos = [1,6];
der_neg = [4,9];

indices = zeros(1,length(der_pos));
for i = [1:length(der_pos)]
    [peak, index] = max(interpolated(der_pos(i):der_neg(i)));
    indices(i) = index + der_pos(i) - 1;
endfor

indices % gives [2,8]

但有没有更简洁的方法呢?

2 个答案:

答案 0 :(得分:1)

这是一个示例代码。函数findpeaks返回所有峰值。然后循环保持所需范围内的峰值指数。

我添加了一个测试,以避免在没有找到峰值时出现错误(索引将为-1),并且如果找到两个峰值则保持第一个峰值。如果要在一个间隔内保留所有峰值,可以使用cell

interpolated = [1,5,3,2,7,10,8,14,4];
der_pos = [1 6 7 ];
der_neg = [4 9 8];

[~,i]=findpeaks(interpolated);
indices= -1+zeros(size(der_pos,2),1);
for loopi = 1:length(i)
    val = i(i>=der_pos(loopi)&i<=der_neg(loopi));
    if ~isempty(val)
        indices(loopi) = val(1);
    end
end

答案 1 :(得分:1)

这是一种方式:

interpolated = [1,5,3,2,7,10,8,14,4]; % data
der_pos = [1,6]; % data
der_neg = [4,9]; % data
m = bsxfun(@ge, 1:numel(interpolated), der_pos(:)) .* ...
    bsxfun(@le, 1:numel(interpolated), der_neg(:)); % each row is a mask that contains
    % 1 for values in the interval and 0 for values outside the interval
m(~m) = NaN; % replace 0 by NaN
[val, result] = max(bsxfun(@times, m, interpolated(:).'), [], 2); % val is the maximum 
    % of each row, and result is its column index. The maximum is 1 for rows that
    % contain at least a 1, and NaN for rows that only contain NaN
result(isnan(val)) = 0; % If the maximum value was NaN the result is set to 0
    % (or maybe use NaN), to indicate that the interval was empty

这为空间隔提供了0。例如,der_pos = [1,6,8]; der_neg = [4,9,6];生成result = [2;8;0]

区间可能重叠。例如,der_pos = [1,6,3]; der_neg = [4,9,7];生成result = [2;8;6]