How to find intersection between two outputs?
1 vue (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Dear Coder,
I have to output generated from KSDENSITY, namely f_smoke and f_Nonsmoke. The idea was to find intersection between the f_smoke and f_Nonsmoke. To achieve this, I used the function INTERSECT. However, MATLAB return me 1×0 empty double row vector instead.
C = intersect(f_smoke,f_Nonsmoke);.
I expect, the intersection should occur as depicted in the figure
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/166248/image.jpeg)
Any idea what I have been missing?. The full code is as below. The patients.mat is an in-build matlab mat file (Version 2017).
load patients
[tf,Ioc_Alert_LessThree] = find (ismember(Smoker, 1));
for i = 1: length (tf)
M (i,1) = Height (tf(i));
end
[tgf,Ioc_Alert_two] = find (ismember(Smoker, 0));
for i = 1: length (Ioc_Alert_two)
M (i,2) = Height (tgf(i));
end
M(M == 0) = NaN;
[f_smoke,xi_smoke] Th= ksdensity(M (1:end,2));
[f_Nonsmoke,xi_Nonsmoke] = ksdensity(M (1:34,1));
plot (xi_smoke, f_smoke);
hold on
plot (xi_Nonsmoke, f_Nonsmoke);
C = intersect(f_smoke,f_Nonsmoke);
Thanks for the time and idea!
0 commentaires
Réponse acceptée
dpb
le 23 Juil 2017
What you're missing is that intersect is a comparison of the elements in the two arrays for exact equality of the members thereof, not a solution to the geometric solution of the intersection of two functions. Even if there had been a point or two that were absolutely identical (to the last bit, remember?) all you would have gotten would have been that one point and it could have been anywhere along the path that just happened to return the same pdf estimate from the two distributions.
What you need to do is to solve for the intersection by writing the difference and find the zero --
On the way, let's make use of some of the more user-friendly Matlab syntax features, ok?
s=load('patients'); % load the data into structure in preparation for...
pat=struct2table(s); % creating a table structure from it...
pat.Gender=categorical(pat.Gender); % just a sample cleanup to turn from cellstr to categorical
[fSmk,xSmk]=ksdensity(pat.Height(pat.Smoker==true)); % fit the empircal density to smokers
[fNSmk,xNSmk]=ksdensity(pat.Height(pat.Smoker==false)); % and non in turn...
Now comes "the trick"...
Build an anonymous function that computes the output difference between the two epdf's as function of the independent variable...use interp1 because the form is numerical, not functional so must interpolate to find points other than those given explicitly.
fnX=@(x) interp1(xSmk,fSmk,x)-interp1(xNSmk,fNSmk,x)
fnX =
@(x)interp1(xSmk,fSmk,x)-interp1(xNSmk,fNSmk,x)
>> fnX(65) % just a sample use of the function to check it works...skip this, just demo
ans =
-0.0346
Now use the function we just defined in fzero to find the intersection point--
>> X0 =fzero(fnX,65) % solve for the intersection; use 65 as initial guess
X0 =
67.5852
>>
10 commentaires
Plus de réponses (2)
Geoff Hayes
le 23 Juil 2017
balandong - remember, the data that you are plotting are doubles and you are drawing a curve where every two consecutive points is "connected" to each other. So when the two curves are drawn, their intersection (where the two curves cross) may not be represented by data from your sets...and so intersect is not guaranteed to be non-empty. Consider the following
plot (xi_smoke, f_smoke, 'r*');
hold on
plot (xi_Nonsmoke, f_Nonsmoke,'g*');
Each point from the first set is represented by a red star, and each from the second set by a green star. Now when you run the code, you can see while there are points close to one another, there doesn't appear to be any that actually intersect.
I suspect that you will need to loop through your data and try to find the two (or more points) that are "close" to one another using a Euclidean or some other distance metric. You may be able to discover the "intersection" from those points.
Image Analyst
le 23 Juil 2017
You can do it approximately and numerically by using comparison to find the index where the one curve goes above or below the other curve. Let's say non-smokers are red (to the right because they live longer) and smokers are above and to the left in blue. Find the index where the blue dips below the red:
index = find(f_smoke < f_Nonsmoke, 1, 'first');
% Get values of the two curves at that index.
smokeCrossoverValue = f_smoke(index);
nonsmokeCrossoverValue = f_Nonsmoke(index);
If the x value is not the index, then you can get the x value (Age, I presume) by indexing it:
ageAtCrossover = x(index);
If you want you could home in on it a little more by doing bilinear interpolation between index and index-1.
4 commentaires
Image Analyst
le 24 Juil 2017
Right. I agree it turned out to be trickier than I thought because they don't have the same x-values.
Voir également
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!