How to find a unique point of a set of data

5 views (last 30 days)
I am given a set of data, P and Phase. I have plotted this data and now I want to find a point on the line which can be used to characterize the line - so for example the inflection point, which should be unique. Probably I will have to interpolate the data first, maybe using:
P_intrp = linspace(min(P),max(P),100)
data_intrp = interp1(P,Phase,P_intrp,'spline');
But what now? I think I can find the inflection point by setting the second derivative to 0. There is no point in my line with first derivative equal to 0.
idx = find(P,diff(diff(data_intrp)) = 0);
P_infl = P(idx);
Phase_infl = data_intrp(idx);
I don't know, if this would work. It's important to me to know which value of P belongs to the inflection point. I also want to know the corresponding Phase.
further information: I want to find such a unique point, in order to find out how the following lines can be obtained from each other just by displacement:

Accepted Answer

Star Strider
Star Strider on 17 Jan 2017
If you want to inflection points in the data you plotted over the range that you plotted, you might not be successful. I don’t see any inflection points.
I would use the gradient function (not diff) to calculate the derivatives, since the output is the same length as the input vector, and this simplifies your code.
  2 Comments
Luki
Luki on 18 Jan 2017
you're right. I have replaced diff by gradient, but my result is a vector with only 0. So it seems I have to find a different way of characterizing the curves. I need to find a point on each curve, which I can compare to the equivalent point on the other curves. Is there even a way of doing this? - Please see my comment on John D'Errico's answer as well.

Sign in to comment.

More Answers (2)

John D'Errico
John D'Errico on 17 Jan 2017
This is a moderately ill-posed problem. Not as easy as you will hope to see. The problem is, differentiation is a noise amplification process. Two derivatives are worse than one. And, since an inflection point is equivalent to finding a zero of the second derivative, this will be predictably difficult.
The effective result is that inflection point will be difficult to pin down. Looking at it another way, if you wanted to put confidence intervals around the location of that inflection point, they would be fairly wide.
So, how would I solve it? I really don't know how much data you have (i.e., how many points are there in each curve?) nor do I have the actual data you have plotted.
I would not use a tool like gradient, or diff, as those tools are only finite difference approximations. They will yield approximations for the second derivative at fixed locations.
A better choice in general for such a problem is a spline. Again, I don't have your data, so I cannot do any experimentation. A simple solution might be to use a cubic smoothing spline, differentiate twice to get a piecewise linear second derivative curve, then solve for the point where that curve crosses zero. You could also do something similar using my SLM Toolbox.
  3 Comments
Stephen23
Stephen23 on 18 Jan 2017
Edited: Stephen23 on 18 Jan 2017
"Is there a more or less easy way of doing this?"
see my answer
John D'Errico
John D'Errico on 18 Jan 2017
Edited: John D'Errico on 18 Jan 2017
What I said is that point of inflection is somewhat difficult to locate accurately, especially if your curves have ANY noise in them, and virtually anything taken from real life will have some amount of trash in it.
However, if you want an example of how I would solve this, I'll use Stephen's example curves.
m = 3;
adj = [0.8;0.9;1];
X = 0:0.1:pi;
M = 1+cos(pi-adj*X);
M = bsxfun(@times,adj,M);
S = cell(1,m);
Spp = S;
inflectX = zeros(1,m);
for i = 1:m
S{i} = slmengine(X,M(i,:),'knots',10,...
'increasing','on','jerk','negative',...
'result','pp');
Spp{i} = fnder(S{i},2);
inflectX(i) = slmsolve(Spp{i},0);
end
So the predicted inflection points are:
inflectX
inflectX =
1.9632 1.7456 1.5706
The call to slmengine posed two constraints on the result:
1. That the curve is a monotonic increasing function of X
2. That the THIRD derivative is everywhere negative. The third derivative of a function is often called the jerk, or sometimes jolt. I've used jerk in SLM, since it seems to be the more common usage in my experience.
The application of those constraints, as well as the use of a smoothing tool to do the fit means you will get a more robust measure of the location of the inflection point than you would from an interpolating spline.
Even so, expect that estimation of the inflection point to be somewhat poor, due to the problems I pointed out above.
To use the tools above, you need to download my SLM toolbox of course. As well, it uses the optimization toolbox, so you need that too.

Sign in to comment.


Stephen23
Stephen23 on 18 Jan 2017
Edited: Stephen23 on 18 Jan 2017
If the data is reasonably smooth, then fitting a spline may be a suitable method, together with the function ppdiff (available as part of the splinefit submission on FEX), of locating a point of inflection:
% Fake data (each row is one line):
adj = [0.8;0.9;1];
X = 0:0.1:pi;
M = 1+cos(pi-adj*X);
M = bsxfun(@times,adj,M);
% Identify inflection points:
xinf = NaN(size(adj));
yinf = NaN(size(adj));
for k = 1:numel(adj)
pp = spline(X,M(k,:));
d1 = ppdiff(pp);
d2 = ppdiff(d1);
xinf(k) = fzero(@(x)ppval(d2,x),[X(1),X(end)]);
yinf(k) = ppval(pp,xinf(k));
end
plot(X,M.','k-',xinf,yinf,'ro')
  1 Comment
Luki
Luki on 18 Jan 2017
wow, I appreciate your answer! Still, it seems a little bit too difficult for me (I'm new to matlab, and actually also to programming). If there is no other way, I will consider using your solution. I figured, maybe there is a way of fitting a line to my curves and then finding the point where the slope of the line is steepest.

Sign in to comment.

Categories

Find more on Descriptive Statistics 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!