How to extrapolate an x value from a fitting curve?

Hello everyone,
I'm kind new to Matlab.
I have a set of data, from which I obtained a fitting curve by interpolation using Fitting Curve toolbox. This is the essential code I'm using:
%example values
xvalues = [10; 12; 22; 28]
yvalues = [1; 2; 3; 4]
% Fit model to data.
[fitresult, gof] = fit( xvalues, yvalues, 'linearinterp', 'Normalize', 'on' );
% Plot fit with data.
figure( 'Name', 'untitled fit 1' );
h = plot( fitresult, xvalues, yvalues );
Later, I would like to obtain the exact value from the fitting curve at a certain value on the y axis (that, obviously, is not contained in the yvalues vector). The problem is that the fit function does not return "fitresult" as a vector, so i don't know hot to do that. I know that it could be easily done graphically, but i need a code to automatize the process. What could I try?
I attach an image as graphical explanation:
EDIT
  • I want to get an x value from a known y value;
  • I can't use interp1 for what I know, because "fitresult" is a cfit and it is not a vector;
  • I can't use x(fitresult==y_known_value) because it would return the error: "Operator '==' is not supported for operands of type 'cfit' ".
  • Found a similiar problem here: Getting x for a given y value from a cfit object - MATLAB Answers - MATLAB Central (mathworks.com), I followed Steven Lord's method and I got this solved. The exact code is posted as answer to this topic.
Thank you all for help!

답변 (4개)

David Hill
David Hill 2022년 10월 24일
feval(fitresult,xvalue)

댓글 수: 1

Thank you, but here we have the same problem as the answer from dpb:
as you can see from the image I posted, I know the y value and I want to get the corresponding x value. So, using feval would not work, 'cause xvalue is what I want to get, and it can't be my input.

댓글을 달려면 로그인하십시오.

dpb
dpb 2022년 10월 24일
xvalues = [10; 12; 22; 28];
yvalues = [1; 2; 3; 4];
% Fit model to data.
[fitresult, gof] = fit( xvalues, yvalues, 'linearinterp', 'Normalize', 'on' );
h = plot( fitresult, xvalues, yvalues );
hold on
X=25;
hP=plot(X,fitresult(X),'k*');
hF=gcf; hLg=findobj(hF,'type','Legend');
hLg.Location='northwest';
See fit documentation; the fit object evaluates the fit automagically for the points passed it...

댓글 수: 3

Thank you, but in your example you're giving a value from the x axis as it is known, to get the corresponding value on the y axis.
I have to do exactly the opposite: as you can see from the image I posted, I know the y value and I want to get the corresponding x value. So, writing fitresult(x_value) would not work.
The problem here, maybe, is that I want to get a value from the indipendet variable knowing the dependent one; and i can't use interp1 (I think) because I don't have a vector.
OK, I overlooked the original intent, sorry.
Since you're interpolating and not fitting a single expression, the resultant fit object is a piecewise polynomial and since it is linear and you're interpolating, then there's no reason to not just simply use interp1 on the original input data in the backwards lookup...
xvalues = [10; 12; 22; 28];
yvalues=[1:4].';
Y=3.5;
X=interp1(yvalues,xvalues,Y)
X = 25
Now, direct interpolation of your y-values vector with interp1 will mean it will have to be monotonic and unique; if that may not be so in the final dataset, then simply redo the fit t'other way 'round; I believe it will handle that case with the p-p instead (but I didn't test it).
xvalues = [10; 12; 22; 28; 12];
yvalues=[1:4 0].';
fitrev=fit(yvalues,xvalues,'linearinterp','Normalize', 'on' );
Y=3.5;
X=fitrev(Y)
X = 25
And, indeed, the pp serves the trick with non-monotonic data values -- although as @Star Strider notes, it would require deciding which section of the overall the lookup value is supposed to be in to get the result between 28;12 instead of that between 22;28 in the above.
Only you know what the real application is....

댓글을 달려면 로그인하십시오.

Star Strider
Star Strider 2022년 10월 24일
You can eliminate the monotonicity problem by first selecting the region of the desired value —
xvalues = [10; 12; 22; 28];
yvalues = [1; 2; 3; 4];
yq = 3.5;
idx = find(diff(sign(yvalues - yq)));
ixr = [-1 0 1]+idx;
xq = interp1(yvalues(ixr), xvalues(ixr), yq)
xq = 25
A more robust approach to defining ‘ixr’ (and the interpolation results), especially if it contains more than one value, is:
for k = 1:numel(idx)
ixr = max(1,idx(k)-1) : min(numel(xvalues),idx(k)+1);
xq(k) = interp1(yvalues(ixr), xvalues(ixr), yq)
end
xq = 25
This prevents ‘ixr’ from referencing indices beyond the index range of the vectors being interpolated.
.
Bruno Galizia
Bruno Galizia 2022년 10월 24일
편집: Bruno Galizia 2022년 10월 24일

0 개 추천

Thank you all for your answers.
Anyway, I got a working code by checking here:
So, that's what I did:
xvalues = [10; 12; 22; 28]
yvalues = [1; 2; 3; 4]
y_known = 3.5950
% Fit model to data.
[fitresult, gof] = fit( xvalues, yvalues, 'linearinterp', 'Normalize', 'on' );
ftogetx = @(x) y_known - fitresult(x);
x_to_find = fzero(ftogetx, 0)
plot(fitresult, xvalues, yvalues)
hold on
plot(x_to_find, y_known, "k*")

댓글 수: 1

Running that for the record —
xvalues = [10; 12; 22; 28]
xvalues = 4×1
10 12 22 28
yvalues = [1; 2; 3; 4]
yvalues = 4×1
1 2 3 4
y_known = 3.5950
y_known = 3.5950
% Fit model to data.
[fitresult, gof] = fit( xvalues, yvalues, 'linearinterp', 'Normalize', 'on' );
ftogetx = @(x) y_known - fitresult(x);
x_to_find = fzero(ftogetx, 0)
x_to_find = 25.5700
plot(fitresult, xvalues, yvalues)
hold on
plot(x_to_find, y_known, "k*")
.

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Get Started with Curve Fitting Toolbox에 대해 자세히 알아보기

제품

릴리스

R2022a

질문:

2022년 10월 24일

댓글:

2022년 10월 24일

Community Treasure Hunt

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

Start Hunting!

Translated by