Piecewise non-linear curve fitting for a specific type of data
81 views (last 30 days)
Show older comments
I am trying to fit numerous data sets with three distinct regions. Please review the attached image or use these data points for a sample set:
x = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]
y= [0.1503,0.1502,0.1505,0.1511,0.1643,0.1750,0.1863,0.1993,0.2152,0.2194,0.2207,0.2261,0.2240,0.2256,0.2130,0.2007,0.1918,0.1799,0.1674,0.1596,0.1513,0.1506,0.1502,0.1504,0.1504,0.1505,0.1502,0.1510,0.1504,0.1505]
Essentially I want a linear region, a non-linear region (TDB what is best, happy to start with cubic polynomial), followed by another linear region. Ideally I want to determine the best location for the transition points and fit coefficients for each region. I am wanting to explore forcing the transition to occur at an actual data point but also in between data points if that provides the best fit. In either case, I want the result to be a continuous function
I have started looking into John D'Errico's SLM tools, but was not able to determine if what I was after was possible (different orders of fit in different zones, but I don't know where each zone will start). I am now looking at the Fit and Fit-type options, but again not sure if this is the right place.
Here is a crude result I got by using three different polyfit commands. Obviously this fails my requirement of continuity at the transition points since I cannot force polyfit to pass through a specified point:
I welcome any thoughts or input as to the best approach for this type of desired fit. Thanks!
0 Comments
Answers (2)
dpb
on 21 Jan 2016
I don't have time to write the full model at the moment, but the idea would be "piecewise regression". I showed the two straight lines with the variable breakpoint solution here some months back: <Piecewise Regression>
John D'Errico
on 21 Jan 2016
Edited: John D'Errico
on 22 Jan 2016
Yes, you asked this question by mail. But I try not to respond to direct e-mail if I can avoid it, as then I would get overwhelmed with requests.
SLM requires that cubic segments be at least C1, thus continuous and differentiable. By default, they will be C2, so twice differentiable.
You cannot have different orders for each specific segment (though I had once considered offering that option. I had also once considered offering a C0 option. Both of these ideas would have made the fitting and user interface more complex than it already is.)
A simple solution is below:
x = linspace(-pi,pi,100).';
y = max(sin(x),0) + randn(size(x))/100;
slm = slmengine(x,y,'knots',[-pi,-.1 0 .1,pi],'c2','off','linearregion',[-pi,0],'plot','on');
Don't make those points around the transition too close together though, or you can get some strange behavior.
Of course, you can indeed write code using LSQLIN, or even simpler, my own LSE, that will solve the problem with explicitly different orders for each segment, but still at least C0 continuity between segments. Or you can just use backslash. In any event, it requires an appreciation of how to enforce continuity across a breakpoint.
It may help you.
See Also
Categories
Find more on Get Started with Curve Fitting Toolbox 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!