SMH
SMH

Reputation: 1316

find intersection between vectors holding the peaks of two signals

I have two signals and I calculated the local peaks of each signal and saved them in two different vectors for amplitude and another two for timing. I need to get the intersection between peaks. Each peak has a value and a time so I am trying to extract the peaks which has nearly the same amplitude at nearly the same time .. Any help??

My Code:

    [svalue1,stime1] = findpeaks(O1);
    [svalue2,stime2] = findpeaks(O2);
    %note that the peaks count is different in each signal
    % This is my try but it is not working
    x = length(intersect(ceil(svalue1),ceil(svalue2)))/min(length(svalue1),length(svalue2));

Upvotes: 1

Views: 123

Answers (1)

rayryeng
rayryeng

Reputation: 104535

It is my understanding what you want to determine those values in svalue1 and svalue2 that are similar to each other, and what's more important is that they are unequal in length.

What you can do is compare every value in svalue1 with every value in svalue2 and if the difference between a value in svalue1 and a value in svalue2 is less than a certain amount, then we would classify these two elements to be the same.

This can be achieved by bsxfun with the @minus function and eliminating any sign changes with abs. After, we can determine the locations where the values are below a certain amount.

Something like this:

tol = 0.5; %// Adjust if necessary
A = abs(bsxfun(@minus, svalue1(:), svalue2(:).')) <= tol;
[row,col] = find(A);
out = [row,col];

tol is the tolerance that we would use to define whether two values are close together. I chose this to be 0.5, but adjust this for your application. out is a 2D matrix that tells you which value in svalue1 was closest to svalue2. Rather than giving a verbose explanation, let's just show you an example of this working and we can explain along the way.


Let's try this on an example:

>> svalue1 = [0 0.1 1 2.2 3];
>> svalue2 = [0.1 0.2 2 3 4];

Running the above code, we get:

>> out

ans =

     1     1
     2     1
     1     2
     2     2
     4     3
     5     4

Now this makes sense. Each row tells you which value in svalue1 is close to svalue2. For example, the first row says that the first value in svalue1, or 0 is close to the second value in svalue2 or 0.1. The next row says that the second value of svalue1, or 0.2, is close to the first value of svalue2, or 0.

Obviously, this operation includes non-unique values. For example, the row with [1 2] and [2 1] are the same. I'm assuming this isn't a problem, so we'll leave that alone.


Now what I didn't cover is whether the peaks also happen within the same time value. This can be done by performing another bsxfun operation on the time vector values of stime1 and stime2 much like we did with svalue1 and svalue2, and performing a logical AND operation between the two matrices. Should the peaks be the same in both amplitude and time, then the result follows.... so something like this:

tol_amplitude = 5; %// Adjust if necessary
tol_time = 0.5;
A = abs(bsxfun(@minus, svalue1(:), svalue2(:).')) <= tol_amplitude;
Atime = abs(bsxfun(@minus, stime1(:), stime2(:).')) <= tol_time;
Afinal = A & Atime;
[row,col] = find(Afinal);
out = [row,col];

You'll notice that we have two thresholds for the time and the amplitudes. Adjust both if necessary. out will contain the results like we saw earlier, but these will give you those indices that are close in both time and amplitude. If you want to see what those are, you can do something like this:

peaks = [svalue1(out(:,1)) svalue2(out(:,2))];
times = [stime1(out(:,1)) stime2(out(:,2))];

peaks and times will give you what the corresponding peaks and times were that would be considered as "close" between the two signals. The first column denotes the peaks and times for the first signal and the second column is for the peaks and times for the second signal. The difference between columns should be less than their prescribed thresholds.

Upvotes: 1

Related Questions