Piecewise non-linear curve fitting for a specific type of data

81 views (last 30 days)
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!

Answers (2)

dpb
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
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.
As it turns out, I see this newly posted tool on the FEX.
It may help you.
  1 Comment
Trey Gilliam
Trey Gilliam on 22 Jan 2016
Thank you this is helpful! For now I am exploring the ppfit function that you pointed to on the FEX with an additional minimization step added to locate the optimum break points to minimize error. One nice thing about SLM that I am not seeing here is the ability to prescribe things such as concavity, etc. Perhaps I will look again at the SLM tools. Again, I have a little more work to do with either package given that I do not know where my breakpoints will be for any given data set, and I would like to automate their placement. And I understand your stance on email questions. I didn't read your profile request to avoid direct emails until after I used the contact feature :).

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!