MATLAB Answers

Determine the location of max curvature for a set of data

62 views (last 30 days)
Kaindl
Kaindl on 14 Aug 2017
Commented: Cong Liu on 2 Feb 2021
In order to find the max curvature, I am using polyfit on my data with which I can calculate the derivatives and therefor the curvature. Unfortunately it is not precise enough and so the max curvature is not right there, where it is supposed to be. I tried higher order, diff, and other fits, however I couldn't find a satisfying solution. Which bugs me quite a bit, because it seems to me like a simple task (at least i thought so). You can easily determine the point of max curvature by just looking at the plot. At the Picture you can see, that the max curvature is at around 7.5, but it should be at 11.
Maybe somebody can Point me in the right direction.

Accepted Answer

John D'Errico
John D'Errico on 14 Aug 2017
Edited: John D'Errico on 14 Aug 2017
If I had a nickel for every time someone asked a similar question, I won't say I'd be rich, but at least I'd get tired of rolling up those nickels and carrying them to the bank.
A problem is that it is easy to see something in your mind. You say, thats what I want to see. But doing the computation can be sometimes less easy. Computing the derivative(s) of a noisy function, especially when the data is not equally spaced is what is called an ill-posed problem. It amplifies any noise in the data. And that amplification can be significant. Finding the location of a second derivative max for noisy data can be nasty as hell to do.
So what would I suggest?
Don't use polyfit!!!!!!! Using a high order polynomial here is absolutely insane. Raising the order of the polynomial is insanity raised to a power. Run as fast as you can, away from polyfit!
I don't have your data, so I can't give you much of an example. In general, a far better choice will be a spline model. If you attach your data in a .mat file to a comment, I can give you a decent example of how I would approach the problem.
x = linspace(-5,5,100);
y = exp(-x.^2) + sin(x/2);
plot(x,y,'o'),grid on
This curve has NO noise in it at all. So I can use a simple interpolating spline to fit it.
pp = spline(x,y);
Now, find the location of the max and min of the second derivative of the curve. I'll use my slmpar tool, as found in my SLM toolbox, on the File Exchange.
[fppmax,fppmaxloc] = slmpar(pp,'maxfpp')
fppmax =
1.0405
fppmaxloc =
-1.2626
[fppmin,fppminloc] = slmpar(pp,'minfpp')
fppmin =
-2.0011
fppminloc =
0.050505
In fact, I'd probably not have picked that spot for the maximum of the second derivative by eye, but that location does make sense.
Dp you want to see the second derivative function plotted? This will give you a hint as to whether it was successful.
If my data was noisy, but equally spaced in x (as it is here, but with noise added on) then I would use either a smoothing spline of some sort (SLM will do this nicely) or I would use a Savitsky-Golay filter.
If the data is unequally spaced AND noisy, then a smoothing or least squares spline of some sort is your only viable choice.
  3 Comments
Cong Liu
Cong Liu on 2 Feb 2021
Thank you for sharing.
Why do you use fnder to find the derivative? Can you use ODE45? what is the differences between these two?

Sign in to comment.

More Answers (2)


Mads
Mads on 3 May 2018
Edited: Image Analyst on 4 May 2018
Hello
I can't seem to get neither the SLM toolbox or Dirks stuff to locate the corner of this L-curve. Can anyone help?
Here are the data points
eta =
1.2960e-003
1.2960e-003
1.2960e-003
1.2960e-003
1.2960e-003
1.2960e-003
1.2960e-003
1.2960e-003
1.2960e-003
1.2960e-003
1.2960e-003
1.2960e-003
1.2960e-003
1.2960e-003
1.2960e-003
1.2960e-003
1.2960e-003
1.2960e-003
1.2960e-003
1.2959e-003
1.2957e-003
1.2954e-003
1.2947e-003
1.2932e-003
1.2900e-003
1.2833e-003
1.2693e-003
1.2409e-003
1.1848e-003
1.0829e-003
920.7605e-006
712.8970e-006
511.8961e-006
366.8875e-006
280.2828e-006
227.0583e-006
189.2376e-006
160.2095e-006
136.8679e-006
116.7839e-006
99.4034e-006
84.8592e-006
72.8964e-006
63.6574e-006
57.0217e-006
52.1719e-006
48.3709e-006
44.9284e-006
40.8770e-006
35.4289e-006
rho =
3.1455e-003
3.1455e-003
3.1455e-003
3.1455e-003
3.1455e-003
3.1455e-003
3.1455e-003
3.1455e-003
3.1455e-003
3.1455e-003
3.1455e-003
3.1455e-003
3.1455e-003
3.1455e-003
3.1455e-003
3.1455e-003
3.1455e-003
3.1455e-003
3.1455e-003
3.1455e-003
3.1455e-003
3.1455e-003
3.1455e-003
3.1455e-003
3.1455e-003
3.1455e-003
3.1455e-003
3.1456e-003
3.1457e-003
3.1462e-003
3.1476e-003
3.1506e-003
3.1552e-003
3.1602e-003
3.1648e-003
3.1696e-003
3.1756e-003
3.1838e-003
3.1957e-003
3.2144e-003
3.2435e-003
3.2874e-003
3.3530e-003
3.4455e-003
3.5701e-003
3.7457e-003
4.0160e-003
4.5048e-003
5.6426e-003
8.5212e-003
  2 Comments
Mads
Mads on 4 May 2018
Awesome, beautiful. Thanks. If I could set this as "Accepted" I would.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!