how to get common range for several intervals
15 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Hussein Al Jebaei
el 19 de Mzo. de 2022
I am interested to find the common range for several intervals. This common range will not cover all these intervals. For example, for these data:
Data=[26 27
22 23.3
22.5 23.4
22 23
20 23.7
21 23.5
24 25.5
24 24.5
24 24.4];
The common range should be: [ 22.5 , 23 ]
I was using the second answer in this question. But it gives [ 24 , 24.4 ] as an output because its code is biased to find the smallest interval that's why it output [ 24 , 24.4 ] not [ 22.5 , 23 ]. Indeed, I am interested to find the common range containing as much intervals as can, that is the [ 22.5 , 23 ] for the example with data mentioned above.
9 comentarios
Torsten
el 19 de Mzo. de 2022
Find intersection of I1 and I2.
Name it I.
Find intersection of I and I3.
Name it I.
...
Find intersection of I and I_n.
Make a loop.
The last I will be the intersection of all n intervals.
Respuesta aceptada
Torsten
el 20 de Mzo. de 2022
Editada: Torsten
el 21 de Mzo. de 2022
Maybe not the most elegant solution, but it should work:
Data=[26 27
22 23.3
22.5 23.4
22 23
20 23.7
21 23.5
24 25.5
24 24.5
24 24.4];
S = sort(unique(Data(:)));
count = zeros(1,numel(S)-1);
for i = 1:numel(S)-1
I1 = S(i);
I2 = S(i+1);
for j = 1:size(Data,1)
if I1 >= Data(j,1) && I2 <= Data(j,2)
count(i) = count(i) + 1;
end
end
end
k = max(count);
f = find(diff([false,count==k,false])~=0);
[~,p] = max(S(f(2:2:end))-S(f(1:2:end-1)));
disp("Number of Intervals from Data Matrix involved:")
k
disp("Maximum Common Interval is:")
S(f(2*p-1):f(2*p))
Más respuestas (1)
John D'Errico
el 20 de Mzo. de 2022
Editada: John D'Errico
el 20 de Mzo. de 2022
Please stop asking the same question over and over again.
Finding the sub-interval that covers the maximum number of intervals should be equivalent to a combinatoric search, where you will want to consider all possible lower bounds from the set of all lower bounds, then combine them with all possible upper bounds from the upper bounds of the same intervals. If you have n intervals, then this would be a search where you would need to check n^2 possible combinations of bounds. That is not too large, and would take a simple double loop to implement at worst.
First, what is the question? You want a new interval that is entirely contained within the largest number of intervals from the set.
In this example set:
Data=[26 27
22 23.3
22.5 23.4
22 23
20 23.7
21 23.5
24 25.5
24 24.5
24 24.4];
M = mean(Data,2);
W = (Data(:,2) - Data(:,1))/2;
plot([1 1]'*(1:length(M)),[M-W,M+W]','-o')
yline([22.5 23],'r')
There we see the interval you want is contained inside 5 of the data intervals.
We can find that sub-interval using a combinatoric search. The problem is, if you have many intervals, then this search will be time consuming if you used brute force. As well, there may be multiple solutions that cover the same number of data intervals. I assume they would be equally good, although then I would assume you would break ties because you would then ask for the longest such sub-interval.
In my eyes, then the solution would just use a simple loop, or even a double loop. But best would seem to be to just use meshgrid. See the code below.
[LU,intervalscovered,intervallength] = bestintersection(Data)
This code will work nicely for up to perhaps several hundred intervals. More than that will become memory intensive, and a simple double loop might be best.
function [LU,intervalscovered,intervallength] = bestintersection(data)
L = data(:,1);
U = data(:,2);
% how many data intervals
n = numel(L);
[I,J] = meshgrid(1:n);
Li = L(I);
Uj = U(J);
% interval width
Wij = Uj - Li;
% ignore those with negative interval width
ignor = Wij <= 0;
Wij(ignor) = -inf;
Li(ignor) = -inf;
Uj(ignor) = inf;
% how many data intervals does each such interval lie inside?
overlapcount = sum((Li >= reshape(L,[1 1 n])) & (Uj <= reshape(U,[1 1 n])),3);
% find the sub-interval with the maximum coverage. If there is more than
% one such solution, we will choose the one with maximum interval width.
intervalscovered = max(overlapcount,[],'all');
ind = find(overlapcount == intervalscovered);
if numel(ind) == 1
% only one interval was found with the maximum data intervals covered.
% It must be the preferred solution.
LU = [Li(ind),Uj(ind)];
intervallength = Wij(ind);
else
% choose the interval with maximum width, over those found
[~,K] = max(Wij(ind))
LU = [Li(ind(K)),Uj(ind(K))];
intervallength = Wij(ind(K));
end
end
0 comentarios
Ver también
Categorías
Más información sobre Strategy & Logic en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!