function y=piecewise(coef,x)
b1=coef(1); m1=coef(2);
c=coef(3); m2=coef(4);
ix=x>=c;
y(ix)=[b1+c*(m1-m2)+m2*x(ix)];
y(~ix)=[b1+m1*x(~ix)];
y=reshape(y,size(x));
end
Example use; contrived example but works well in general with real data in my experience...
x1=1:5; x2=x1+5; x=[x1 x2];
y=[polyval([1 1],x1) polyval([3 -10],x2)]+rand(size(x));
plot(x,y,'*')
hold on
b=nlinfit(x,y,@piecewise,[1 1 4 3])
b =
1.1746 1.0519 5.5482 3.1284
xh=linspace(x(1),x(end));
yh=piecewise(b,xh);
plot(xh,yh)
ADDENDUM
[dpb wrote earlier comment -- "I've never sat down and done the algebra to write as anything but two linear segments but it would be possible to do the same thing but join a straight line and a quadratic..."]
Well, it dawned on me it isn't difficult to do if one limits the implementation to the one specific case of the quadratic portion being arbitrarily set to one section or the other. Since your data have the nonlinear portion to the right of the breakpoint, I chose to do that case--
function y=piecelinquad(coef,x)
b1=coef(1); m1=coef(2);
c=coef(3); p=coef(4:5);
ix=x>c;
y(ix)=polyval([p b1+c*m1],x(ix)-c);
y(~ix)=b1+m1*x(~ix);
y=reshape(y,size(x));
end
Testing on a couple of artificial datasets such as the one used above, it seems to work well in locating the breakpoint and minimizing overall SSE; I noticed there may be a tendency to place the breakpoint somewhat farther inside the linear section as the overall error can be less with a little overshoot at the breakpoint by the quadratic. All these tests were with a small number of points, however, the more extensive datasets you have could be better behaved.
It raises the question, however, of whether, depending on the actual problem constraints of just using smoothing spline or similar?
Best Answer