how to get common range between 20 intervals?

2 visualizzazioni (ultimi 30 giorni)
I have 20 intervals such as [21,23], [20,22] and [19,20.4]. I want to find the common range (intersection) for those twenty intervals if exists, if not then I want to answer what would be the common range that satisfies the most out of those twenty intervals, such as finding a range that can satisfy around 15 intervals out of the 20. I have seen the following references but they won't work out for my application.

Risposte (3)

John D'Errico
John D'Errico il 22 Feb 2022
Your question is too fuzzy. You want to satisfy some of the intervals. Most. How many is most? And how is a computer to choose? Around 15. What if the desired region of overlap was not contiguous, so broken into disjoint sub-intervals? No problem. :) Seriously, you need to recognize that computers don't do wishy washy very well.
And you don't actually give any specific data, besides a few examples. So let me make some data up.
n = 20;
LB = randn(1,n);
UB = LB + 3 + rand(1,n);
Now plot the various intervals.
N = (1:n);
plot([LB;UB],[N;N],'-o')
Can we find some domain of best approximate overlap, with 15 of the 20 intervals included? Logically, we might look at an appropriate percentile on the lower bounds, then use the reverse percentile on the upper bounds.
overlapfrac = 0.75;
overlapinterval = [prctile(LB,100*overlapfrac),prctile(UB,100*(1-overlapfrac))]
overlapinterval = 1×2
0.2371 2.6529
xline(overlapinterval)
In some cases, the overlap interval may be such that the lower bound is greater then the upper bound. That would tell you no interval exists with the desired property.
Is this the perfect solution? Hardly so, since I honestly have no clue what you really expect. If you want something better, you need to provide answers to the questions I posed above.
  1 Commento
Hussein Al Jebaei
Hussein Al Jebaei il 22 Feb 2022
Thank you for your time and feedback. I am listing below the data for twenty intervals. Clearly there will not be a range that is overlapping between the twenty intervals. Thus, I am aiming to find the range that can contain the most intervals out of those twenty. Say I can find a range that is common to 7 intervals and another range that intersects 10 intervals then the one satifying 10 intervals interests me. I was giving the number 15 as an example. It doesn't have to be 15, it could be 8, 12 or 17...
Data=[25.02675585 27.03344482
25.1270903 27.03344482
25.22742475 27.38461538
21.61538462 23.92307692
22.81939799 24.52508361
25.47826087 27.73578595
25.67892977 27.88628763
24.22408027 25.92976589
26.13043478 27.93645485
25.87959866 28.38795987
23.17056856 24.97658863
26.93311037 28.68896321
23.72240803 25.22742475
27.38461538 29.39130435
21.51505017 23.97324415
28.28762542 29.94314381
20.66220736 23.6722408
21.71571906 24.42474916
21.81605351 24.22408027
22.36789298 24.9264214];

Accedi per commentare.


DGM
DGM il 22 Feb 2022
Modificato: DGM il 22 Feb 2022
Finding a non-empty intersection is easy enough, so I'm going to concentrate on the latter part of the question. I'm sure there are other ways, but this is what I came up with.
% let's say we have a set of intervals in a Mx2 matrix
rng(123)
ivals = [randi([20 60],20,1) randi([40 80],20,1)]
ivals = 20×2
48 66 31 74 29 69 42 65 49 69 37 53 60 54 48 49 39 52 36 65
% pull out the lower and upper boundaries for clarity
LB = ivals(:,1);
UB = ivals(:,2);
% find the intersection
% in this case, the intersection is empty
% so we need to find the smallest nonzero range
% which intersects as many of the intervals as possible
intsect_ivals = [max(LB) min(UB)]
intsect_ivals = 1×2
60 43
% get sorted copies of the boundaries
LBs = sort(LB,'descend');
UBs = sort(UB,'ascend');
[LBs UBs]
ans = 20×2
60 43 50 49 49 52 49 52 48 53 48 54 42 57 41 57 41 57 39 57
% find the span between all lower and upper bounds
% we're only looking for positive nonzero cases
span = UBs.' - LBs;
span(span<=0) = NaN
span = 20×20
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 5 5 6 9 9 14 16 18 NaN NaN 2 2 3 4 7 7 7 7 10 10 15 15 16 19 19 24 26 28 NaN NaN 3 3 4 5 8 8 8 8 11 11 16 16 17 20 20 25 27 29 NaN NaN 3 3 4 5 8 8 8 8 11 11 16 16 17 20 20 25 27 29 NaN 1 4 4 5 6 9 9 9 9 12 12 17 17 18 21 21 26 28 30 NaN 1 4 4 5 6 9 9 9 9 12 12 17 17 18 21 21 26 28 30 1 7 10 10 11 12 15 15 15 15 18 18 23 23 24 27 27 32 34 36 2 8 11 11 12 13 16 16 16 16 19 19 24 24 25 28 28 33 35 37 2 8 11 11 12 13 16 16 16 16 19 19 24 24 25 28 28 33 35 37 4 10 13 13 14 15 18 18 18 18 21 21 26 26 27 30 30 35 37 39
% find locations where the minimal nonzero span occurs
candidatemap = span == min(span(:))
candidatemap = 20×20 logical array
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
% these are all intersections which have the same minimal span
% map subscripts are indices into LBs, UBs
[idxL idxU] = find(candidatemap);
idxLU = [idxL idxU];
% since LBs,UBs are sorted, the index pair with the lowest maximum
% includes the largest fraction of the original set of intervals
[~,bestidx] = min(max(idxLU,[],2));
bestLUidx = idxLU(bestidx,:);
bestinterval = [LBs(bestLUidx(1)) UBs(bestLUidx(2))]
bestinterval = 1×2
48 49
  1 Commento
Hussein Al Jebaei
Hussein Al Jebaei il 22 Feb 2022
Thank you for taking the time and writing the detailed answer. I have tried your approach and got the following:
bestinterval =
25.8796 25.9298
I used the following data:
Data=[25.02675585 27.03344482
25.1270903 27.03344482
25.22742475 27.38461538
21.61538462 23.92307692
22.81939799 24.52508361
25.47826087 27.73578595
25.67892977 27.88628763
24.22408027 25.92976589
26.13043478 27.93645485
25.87959866 28.38795987
23.17056856 24.97658863
26.93311037 28.68896321
23.72240803 25.22742475
27.38461538 29.39130435
21.51505017 23.97324415
28.28762542 29.94314381
20.66220736 23.6722408
21.71571906 24.42474916
21.81605351 24.22408027
22.36789298 24.9264214];
I have two questions, is there a way to visiualize the intervals in a 2D plot? Also, is there a way to know how many intervals were met by the output value aka, bestinterval?

Accedi per commentare.


Image Analyst
Image Analyst il 22 Feb 2022
Can you supply some data? What I'd do is to take a histogram of all the aggregated data and look for bins that cover all of the range or most of the range. You can examine the counts.
You can also do it yourself manually by making a number line and assigning values. Like
numberLine = linspace(0, 30, 1000);
counts = zeros(1, length(numberLine));
% Add in interval 1
indexRange = numberLine >= interval1Min & numberLine <= interval1Max
counts(indexRange) = counts(indexRange) + 1;
% Now repeat for interval 2.
indexRange = numberLine >= interval2Min & numberLine <= interval2Max
counts(indexRange) = counts(indexRange) + 1;
% etc.
plot(numberLine, counts, 'b-', 'LineWidth', 2);
You can decide what range to take after you examine the counts.
You forgot to attach any data. Doing so would have gotten you a better answer.
  1 Commento
Hussein Al Jebaei
Hussein Al Jebaei il 22 Feb 2022
Thank you for your answer. I am listing below the data for twenty intervals. Should I repeat the input process for the twenty intervals?
Data=[25.02675585 27.03344482
25.1270903 27.03344482
25.22742475 27.38461538
21.61538462 23.92307692
22.81939799 24.52508361
25.47826087 27.73578595
25.67892977 27.88628763
24.22408027 25.92976589
26.13043478 27.93645485
25.87959866 28.38795987
23.17056856 24.97658863
26.93311037 28.68896321
23.72240803 25.22742475
27.38461538 29.39130435
21.51505017 23.97324415
28.28762542 29.94314381
20.66220736 23.6722408
21.71571906 24.42474916
21.81605351 24.22408027
22.36789298 24.9264214];

Accedi per commentare.

Prodotti


Release

R2021b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by