Extract maximum values from two different vectors when their associated location vectors crosses
Show older comments
Dear all,
I have four vectors, two with peak values and two vectors with associated location values based on two peak analysis.
loc1=[10.4 15.8 29.2 32.1 35.9];
loc2=[10.1 15.2 35.6];
pks1=[10 1 5 4 100];
pks2=[8 5 1000];
I want create a new vector with the maximum value from vector pks1 and from pks2 when loc1 and loc2 have the approximately same value (~+-2).
I.e. loc1 and loc2 cross at position 1,2 and 5 (10.1 and 10.4, 15.2 and 15.8, 35.6 and 35.9), so my new vector will be: final=[10 5 5 4 1000].
Can anyone help me out?
Thanks in advance!
6 Comments
Adam Danz
on 29 Sep 2019
Why wouldn't it be [10 5 1000]. Where does the additional 5 and 4 come from?
Askeladden2
on 29 Sep 2019
the cyclist
on 29 Sep 2019
Is the following an accurate algorithm for what you want to do?
- First, select all of the peaks defined by pks1
- Next, if a value of loc2 is near loc1, and the associated value of pks2 is larger than pks1, use the pks2 value instead.
Adam Danz
on 29 Sep 2019
Finding the max pks values for loc values that are within 2 units is easy. It's just unclear what to do with the unpaired loc values.
% Find indices of loc1 & loc2 that are within 2 units of each other
% locsAreClose(n,m) determines if loc1(n) and loc2(m) are within +/-2
locsAreClose = abs(loc1(:)-loc2(:).')<=2; %rows@loc1, cols@roc2
% Find the max between all pks pairs
maxPairs = max(pks1(:),pks2(:).');
% Output the max for each pair
out = maxPairs(locsAreClose);
Adam Danz
on 29 Sep 2019
Per Vatsvag's answer moved here as a comment.
Thanks for all replies
The cyclist: Yes ,the algorithm you describe is correct!
Adam Danz: In principle I need to account for all peaks in pks1, but also considered that the maximum peak force may occur in the second sensor (pks2) for an event where both the sensors are triggered. The pks1-sensor have triggered 5 times and the pks2-sensor have triggered 3 times, which means that my new vector must contain 5 values. Since the second sensor have triggered at the same time (+-2s) as the first sensor (pks1) then I want to use the maximum of those.
Accepted Answer
More Answers (2)
the cyclist
on 29 Sep 2019
% The data
loc1=[10.4 15.8 29.2 32.1 35.9];
loc2=[10.1 15.2 35.6];
pks1=[10 1 5 4 100];
pks2=[8 5 1000];
% Find the values of loc2 that are close to loc1, and their corresponding
% indices
[isClose,closeIndex] = ismembertol(loc2,loc1,2,'DataScale',1);
% Define the initial guess of the true peaks to be all the pks1 values
truePeaks = pks1;
% Overwrite the close ones with pks2
truePeaks(closeIndex(isClose)) = pks2(isClose);
3 Comments
the cyclist
on 29 Sep 2019
Edited: the cyclist
on 29 Sep 2019
Extended to your three-variable problem:
% The data
loc1=[10.4 15.8 29.2 32.1 35.9];
loc2=[10.1 15.2 35.6];
loc3=[15.3 29 35.6 44];
pks1=[10 1 5 4 100];
pks2=[8 5 1000];
pks3=[7 6 50 90];
% Find the values of loc2 that are close to loc1, and their corresponding
% indices
[isClose,closeIndex] = ismembertol(loc2,loc1,2,'DataScale',1);
% Define the initial guess of the true peaks to be all the pks1 values
truePeaks = pks1;
% Overwrite the close ones with pks2
truePeaks(closeIndex(isClose)) = pks2(isClose);
% Find the values of loc3 that are close to loc1, and their corresponding
% indices
[isClose,closeIndex] = ismembertol(loc3,loc1,2,'DataScale',1);
% Overwrite the close ones with pks3
truePeaks(closeIndex(isClose)) = pks3(isClose);
Note that the only change (besides your new data) was to repeat the finding close values and overwriting, which is done in exactly the same way.
Also, as an aside, it is generally a terrible idea to name your variable dynamically (loc1, loc2, etc). It would have been better to use cell arrays: loc{1}, loc{2}, etc.
It's not as simple as that. loc1(2) is close to loc2(2) and loc3(1) and for this data, the pks3(1) value is greatest so your solution works. Change the pks3(1) value so that it's less than pks(2) and the solution no longer works.
% v-- now pks2(2) > pks3(1)
pks2=[8 7 1000];
pks3=[5 6 50 90];
the cyclist
on 29 Sep 2019
Yeah. Ugh.
Askeladden2
on 29 Sep 2019
0 votes
6 Comments
Adam Danz
on 29 Sep 2019
I updated my answer to show a solution for 3 pks/loc vectors. It combines loc2&3 as well as pks 2&3 so this answer can be expanded to any number of pks and loc vectors.
the cyclist
on 30 Sep 2019
Moved Per Vatsvag's "answer" here (and formatted it a bit), because it was actually a comment.
Dear Adam,
I am not able to get your code with 3 variables working properly.
A new example:
% Sensor 1 (15 events)
time1=[1213 1373 1795 2659 4348 5020 5491 5667 8537 8953 9173 10536 10826 10991 11489];
pks1=[404 998 891 1844 329 428 1025 335 2354 549 997 438 7531 614 545];
% Sensor 2 (14 events)
time2=[1373 1795 2659 3051 4348 5020 5491 5667 8537 8953 9173 10826 10991 11489];
pks2=[1372 1065 1327 323 568 461 989 504 1322 532 440 7650 566 484];
% Sensor 3 (11 events)
time3=[1373 1795 2659 4348 5491 8537 8953 9173 10826 10991 11489];
pks3=[1547 920 931 601 1058 1628 652 638 5332 741 397];
I have in total 16 different "events" from these sensors.
My new vector shall be, a= [404 1547 1065 1844 323 601 461 1058 504 2354 652 997 438 7650 741 545];
If I use your code and combine time1 and time2 into 1 vector I will have a new vector (1x11) which is a12=[1547 1065 1844 601 1058 2354 652 997 7650 741 545].
If I combine time2 and time3 into 1 vector I will have a new vector (1x15) which is a23=[404 1547 1065 1844 601 461 1058 504 2354 652 997 438 7650 741 545];
I am then missing event #5, peak=323 at time= 3051 which occur on sensor 2.
Do you have any suggestions?
Thank you in advance.
the cyclist
on 30 Sep 2019
@Per,
I think you probably don't fully realize this, but the problem is that you keep slightly changing the requirements for the solution.
First, it was just that you needed to compare a 2nd set of peaks.
Next, it was that you had a 3rd set of peaks -- but it seemed that the 1st set was "definitive", in that it had all the possible locations.
Now, it seems that locs1 does not have all the locations, so we need to modify again.
So, lesson for next time -- lay out the whole problem at the beginning.
Also, please try to see how Adam and I have been using this forum. Answers only for things that are actually answers, and comments when you are replying to something someone else wrote.
This is an interesting project.
In your original question you described, "I need to account for all peaks in pks1, but also considered that the maximum peak force may occur in the second sensor (pks2)"""
In my multi-vector solution, pks1 & loc1 are the reference vectors which are compared against all other vectors combined. Data from pks1 & loc1 are not combined with any other data.
From your comment above, it seems that you've used a different implementation where loc1 and loc2 (which I assume are time1 and time2, let's not change variable names because that will make it difficult to follow the comments) are combined and then compared against loc3&4.
The correct implementation of my multi-vector answer is to simply substitute your pks and time vectors into the pks and locs variables from my answer.
loc1=[1213 1373 1795 2659 4348 5020 5491 5667 8537 8953 9173 10536 10826 10991 11489];
loc2=[1373 1795 2659 3051 4348 5020 5491 5667 8537 8953 9173 10826 10991 11489];
loc3=[1373 1795 2659 4348 5491 8537 8953 9173 10826 10991 11489];
pks1=[404 998 891 1844 329 428 1025 335 2354 549 997 438 7531 614 545];
pks2=[1372 1065 1327 323 568 461 989 504 1322 532 440 7650 566 484];
pks3=[1547 920 931 601 1058 1628 652 638 5332 741 397];
%% THE REST OF THIS BELOW IS THE SAME AS IN MY ANSWER
loc23 = [loc2, loc3]; % combine them into 1 vector
pks23 = [pks2, pks3]; % combine them into 1 vector
% Find indices of loc1 & loc23 that are within 2 units of each other
locsAreClose = abs(loc1(:)-loc23(:).')<=2; %rows@loc1, cols@loc23
% Find the max between all pks pairs
maxPairs = max(pks1(:),pks23(:).');
maxPairs(~locsAreClose) = -inf;
maxVals = max(maxPairs,[],2); % a vector of all max values
% Output
pksMax = pks1;
pksMax(any(locsAreClose,2)) = maxVals(any(locsAreClose,2));
The result is
pksMax =
Columns 1 through 11
404 1547 1065 1844 601 461 1058 504 2354 652 997
Columns 12 through 15
438 7650 741 545
But that doesn't match your expected output "a" however it does match the expected output of the rule you defined.
For example, your a(5) is 323. My pksMax(5) is 601. The 5th element of locs1 (time1) is 4348 which is close to the 5th element of locs2 and the 4th element of locs3. The associated pks values are [329, 568, 601]. Clearly 601 is the max value. 323 isn't even an option. So either your expected values in 'a' are incorrect or the rule has changed (as the cyclist mentioned above).
Adam Danz
on 30 Sep 2019
ps, the biggest lesson to learn here (and one that most of us learned the hard way) is to have a well planned set of rules before the first line of code is written. That's not to say that you won't need to make small adjustments as you go along. But following a planned sketch is much easier than sketching it out as you go. I'd bet that every 1 minute spent planning an algorithm before implementing it can save 15-30 minutes of troubleshooting and re-writing.
Askeladden2
on 30 Sep 2019
Categories
Find more on Matrix Indexing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!