Speeding up findpeaks in octave using parallel computing

62 Views Asked by At

I am modeling and interference measurement and want to find the number of fringes that cross a detector. The data is fairly dense and it causes problems in findpeaks, and I was trying to use parfor to speed it up. Of course parfor doesn't exist in octave, so I was wondering the best way to handle this issue.

This is what I tried initially;

```
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
```
1

There are 1 best solutions below

3
rahnema1 On

Here is an implementation of findpeaks using regex:

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

That returns the positions of the peaks. Use it as:

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

The Octave implementation of findpeaks uses bsxfun to expand the index vector that require n^2 memory.

UPDATE

Two more options height and dist are added. Moreover the function now has two outputs: pks local maxima and locs peak locations.

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