0

Say s(t) a temporal signal with length(s)=12000000. Some peaks are occuring at variable frequencies (I cannot simply remove these peaks using fft(s) because of this). This peaks have a high amplitude so it is easy for me to find the points in s(t) associated with this peaks using the following command :

s_indices = find(abs(s)>std(s)); %I use std(s) as a threshold for selecting the peaks points associated indices

The idea is to generate N new arrays containing the amplitudes of my signal inbetween those peaks in order to study them separately. As the number of data is high, I want to avoid using a 'for' loop and work with indices. Is there a simple way to do so or am I forced to use a 'for' loop?

Thank you for the time you take considering my question, I will further explain if things are not clear enough.

  • 1
    One answer is not to create new arrays at all. Just work on the subarray in place as `s(s_indices(t):s_indices(t+1))` (maybe adding in a -1 if you don't want both peaks). – beaker Mar 11 '21 at 16:52

1 Answers1

0

array of rows of different lengths

The two first solutions have have runtime growing linearly and takes ~0.5 second for a N = 1e4 (in Octave 6.1.0)

tic; s = randn(N, 1); toc;
tic; s_indices = find(abs(s)>std(s)); toc;

V = []; 
tic; for i = 2:length(s_indices) 
  V{i-1} = s(s_indices(i-1)+1:s_indices(i)-1); 
end; toc

tic; V = arrayfun(@(i) s(s_indices(i-1):s_indices(i)-1), 2:length(s_indices), 'UniformOutput', 0); toc

The following solution creates a sparse matrix whose columns have the values of a slice, and they are padded with zero to the length of the maximum interval.

For N=1e4 it takes about the same time as the solutions above, the difference is that increasing the size to 1.2e6, it produces ~380k slices in 0.6 second (only 20% increase for a 100x longer input). For data of the size you mentioned 12000000 it runs in 2 seconds.

tic;
J = zeros(size(s));
J(s_indices) = 1:length(s_indices);
J = 1 + cummax(J);
I(s_indices) = s_indices;
I = (2:length(I)+1) - cummax(I);
V = sparse(I(s_indices(1):s_indices(end)), J(s_indices(1):s_indices(end)), s(s_indices(1):s_indices(end)));
toc;
Bob
  • 13,867
  • 1
  • 5
  • 27