How can I fit data to a piecewise function, where the breakpoint of the function is also a parameter to be optimised?

82 ビュー (過去 30 日間)
I have data with x and y values. This data should conform to a function: an assymmetric parabola. Here, the parameters that define the shape of the parabola should be different on either side of the maximum point of the parabola i.e. the breakpoint is where the maximum value of y occurs.
I was hoping to use 'fit' and to define an anonymous function for my data. But I'm not able to work out how to define an anonymous, piecewise function, especially where the breakpoint is one of the parameters to be determined by the fitting procedure, as it is not immediately clear from the data itself where the maximum value of y should occur.
Any help would be appreciated.

採用された回答

Matt J
Matt J 2025 年 9 月 30 日 4:09
編集済み: Matt J 2025 年 9 月 30 日 11:20
Once you've chosen the coefficients of the first parabola [a1,b1,c1], the breakpoint is determined from,
d=-b1/(2*a1)
Only the leading coefficient of the second parabola is a free parameter:
F=@(x) asymParabola(-2,1,0,-0.6,x);
fplot(F,[-10,10]);axis padded %example plot
ft = fittype(@(a1,b1,c1,a2, x) asymParabola(a1,b1,c1,a2, x) )
ft =
General model: ft(a1,b1,c1,a2,x) = asymParabola(a1,b1,c1,a2,x)
function y=asymParabola(a1,b1,c1,a2, x)
d=-b1/(2*a1);
b2=-d*2*a2;
c2=polyval([a1,b1,c1],d)-polyval([a2,b2,0],d);
left=(x<=d);
y=x;
y(left)=polyval([a1,b1,c1],x(left));
y(~left)=polyval([a2,b2,c2],x(~left));
end
  6 件のコメント
Rahul
Rahul 2025 年 10 月 2 日 15:09
You're right Torsten that things could be interpreted in this way, and I could have been clearer in my original question.
Image Analyst
Image Analyst 2025 年 10 月 3 日 14:58
@Rahul what would have been best is if you had shown a screenshot of your noisy data plotted, and attached the data so that people would have something to work with.
I think the fit values will change because of noise. With one set of noise, you'd have one set of parabola coefficients but if you had a different set of noise, then you have a different set of coefficients. If there is no noise, there is no need for a fit because you have the analytical formula already.
If you have any more questions, then attach your data and code to read it in with the paperclip icon after you read this:

サインインしてコメントする。

その他の回答 (3 件)

Walter Roberson
Walter Roberson 2025 年 9 月 29 日 21:20
(a1*x.^2 + b1*x + c1) .* (x <= d) + (a2*x.^2 + b2*x + c2) .* (x > d)
Note that for this to work, the coefficients must be constrained to be finite
  2 件のコメント
Paul
Paul 2025 年 9 月 30 日 0:37
Sounds like both sides of the function should have the same value at x = d, at least that's how interpret the question. If so, then I think the function would look something like
(a1*(x-d).^2 + b1*(x-d) + c) .* (x <= d) + (a2*(x-d).^2 + b2*(x-d) + c) .* (x > d)
Rahul
Rahul 2025 年 9 月 30 日 13:57
Thanks Paul, I think this would also work, but as Matt pointed out I think some of extra parameters are not needed (as they are actually constrained by the others). I am not sure how Matlab deals with this in the curve fitting/optimisation algorithms.

サインインしてコメントする。


Catalytic
Catalytic 2025 年 9 月 30 日 14:13
編集済み: Catalytic 2025 年 9 月 30 日 14:18
You can also parametrize the model function directly in terms of the break point coordinates (xbreak, ybreak) and two curvature parameters -
F= @(a1,a2,xbreak,ybreak, x) modelFun(a1,a2,xbreak,ybreak, x);
xbreak=3; ybreak=5;
fplot( @(x) F(-2,-0.6,xbreak,ybreak,x), [1,5]);
xline(xbreak,'--')
fType = fittype(F);
function y=modelFun(a1,a2,xbreak,ybreak, x)
X=x-xbreak;
LHS=(X<=0);
RHS=~LHS;
y=X.^2;
y(LHS)=a1.*y(LHS) + ybreak;
y(RHS)=a2.*y(RHS) + ybreak;
end

Matt J
Matt J 2025 年 9 月 30 日 21:15
編集済み: Matt J 2025 年 10 月 3 日 13:47
Why ? Both parabola can intersect below their respective maxima, and nonetheless the point of intersection can be the maximum y-value of the piecewise function.
If I understand @Torsten, that would be a 6-parameter function,
F=@(x) asymParabola(-2,1,0,-6,5,-20 ,x);
fplot(F,[-10,-1]);axis padded %example plot
function y=asymParabola(a1,b1,c1, a2, s, rightSlope, x)
%Requirements: a1<0, a2<0, s>=0, rightSlope<=0
d=-b1/(2*a1)-s;
c2=polyval([a1,b1,c1],d);
left=(x<=d);
right=~left;
xright=x(right);
y=x;
y(left)=polyval([a1,b1,c1],x(left));
y(right)=a2*(xright-d).^2 + rightSlope*(xright-d) +c2;
end

カテゴリ

Help Center および File ExchangeGet Started with Curve Fitting Toolbox についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by