How to extrapolate an x value from a fitting curve?
117 views (last 30 days)
Show older comments
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!
0 Comments
Answers (4)
dpb
on 24 Oct 2022
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';
3 Comments
dpb
on 24 Oct 2022
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)
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).
dpb
on 24 Oct 2022
xvalues = [10; 12; 22; 28; 12];
yvalues=[1:4 0].';
fitrev=fit(yvalues,xvalues,'linearinterp','Normalize', 'on' );
Y=3.5;
X=fitrev(Y)
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
on 24 Oct 2022
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)
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
This prevents ‘ixr’ from referencing indices beyond the index range of the vectors being interpolated.
.
0 Comments
Bruno Galizia
on 24 Oct 2022
Edited: Bruno Galizia
on 24 Oct 2022
1 Comment
Star Strider
on 24 Oct 2022
Running that for the record —
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*")
.
See Also
Categories
Find more on Linear and Nonlinear Regression 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!