Determine the location of max curvature for a set of data
33 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Kaindl
el 14 de Ag. de 2017
Comentada: Cong Liu
el 2 de Feb. de 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.
0 comentarios
Respuesta aceptada
John D'Errico
el 14 de Ag. de 2017
Editada: John D'Errico
el 14 de Ag. de 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 comentarios
Cong Liu
el 2 de Feb. de 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?
Más respuestas (2)
Image Analyst
el 14 de Ag. de 2017
For what it's worth, take a look at Dirk's file Exchange:
0 comentarios
Mads
el 3 de Mayo de 2018
Editada: Image Analyst
el 4 de Mayo de 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 comentarios
Image Analyst
el 4 de Mayo de 2018
How about looking at distances of the curve from its asymptotes? Try this:
format long g;
format compact;
fontSize = 15;
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]
plot(eta, rho, 'b-', 'LineWidth', 2);
grid on;
axis equal % Make axes equal, otherwise "corner" depends on scaling.
xlabel('eta', 'FontSize', fontSize);
ylabel('rho', 'FontSize', fontSize);
cornerX = min(eta);
cornerY = min(rho);
distancesFromCorner = sqrt((eta - cornerX) .^ 2 + (rho - cornerY) .^ 2);
% Find min distance
[minDistance, indexOfMin] = min(distancesFromCorner);
minEta = eta(indexOfMin)
minRho = rho(indexOfMin)
% Start x axis at 0
xlim([0, max(eta)]);
% Start y axis at 3
ylim([0.003, max(rho)]);
% Get location of axes:
xl = xlim;
yl = ylim;
% Plot a vertical line there.
line([minEta, minEta], [yl(1), minRho], 'Color', 'r', 'LineWidth', 2);
% Plot a horzontal line there.
line([xl(1), minEta], [minRho, minRho], 'Color', 'r', 'LineWidth', 2);
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0, 0.04, 1, 0.96]);
Ver también
Categorías
Más información sobre Surface and Mesh Plots 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!