使用并行计算加速倍频程的查找峰值

Speeding up findpeaks in octave using parallel computing

提问人:James Hendrie 提问时间:11/1/2023 更新时间:11/7/2023 访问量:46

问:

我正在建模和干涉测量,想要找到穿过探测器的条纹数量。数据相当密集,会导致findpeaks出现问题,我试图使用parfor来加快速度。当然,parfor 在八度音阶中不存在,所以我想知道处理这个问题的最佳方法。

这是我最初尝试的;

```
parfor i = 1:N
  start = round(((i-1)/N)*length(IT))+1;
  stop = round((i/N)*length(IT));
  partime = time(start:stop);
  [row,col] = findpeaks(IT(start:stop)./max(IT(start:stop)));  % Fringe Frequency
  pklk = [pklk partime(col)];
end
```
octave parfor octave-gui

评论

0赞 rahnema1 11/1/2023
除非峰值是平坦的,否则这应该返回相同的结果:。无需使用循环。[~,col] = findpeaks(IT); pklk = time(col);
1赞 Cris Luengo 11/1/2023
stackoverflow.com/a/25432257/7328782
1赞 James Hendrie 11/2/2023
@rahnema1;我将一个向量分解成几个部分,因为它太长了,而且我的机器内存不足,无法同时找到峰值。
0赞 James Hendrie 11/2/2023
@CrisLuengo,我认为我的 parfor 实例将需要多个输入变量来运行、IT、启动和停止。这可能只有两个,i 和 IT,但是我如何实现具有多个函数输入的 pararrayfun?

答:

1赞 rahnema1 11/2/2023 #1

以下是使用正则表达式的实现:findpeaks

findpeaks = @(data) regexp(char(sign(diff(reshape(data, 1, []))) + '1'), '21*0') + 1;

这将返回峰值的位置。将其用作:

col = findpeaks(IT); 
pklk = time(col);

的 Octave 实现用于扩展需要内存的索引向量。findpeaksbsxfunn^2

更新

另外两个选项被添加。此外,该函数现在有两个输出:局部最大值和峰值位置。heightdistpkslocs

function [pks, locs]  = findpeaks(data, height, dist)
  % find all peaks
  locs = regexp(char(sign(diff(reshape(data, 1, []))) + '1'), '21*0') + 1;
  % apply MinPeakHeight
  locs = locs(data(locs) > height) ;
  % apply MinPeakDistance 
  [~, isorted] = sort(data(locs), 'descend');
  n = numel(data);
  idx = false(1, n);
  idx(locs) = true;
  for s = reshape(locs(isorted), 1, [])
    if (idx(s))
      idx(max(s - dist, 1):min(s + dist, n)) = 0;
      idx(s) = 1;
    end
  end
  locs = find(idx);
  pks = data(locs);
end

评论

2赞 Cris Luengo 11/2/2023
我以为我已经看到了这一切,但你证明我错了。 寻找山峰...🤯regexp
0赞 James Hendrie 11/7/2023
我会试试这个,谢谢!!
0赞 James Hendrie 11/7/2023
尝试后我有一些问题。然而,首先,这将每次循环迭代的时间减少了一个数量级;现在结果存在差异。我想知道是否是由于我在findpeaks原始代码中设置的限制,我不再设置;例如,峰高和距离(这些不包括在问题的最初陈述中,因为我认为它们可能无关紧要)。