How do I interpolate X values from Y values? (Standard Curve)

I have a set of data that I fitted with a linear fit to create a standard curve and now I'm trying to interpolate unknown x-values for known y-values. I tried using polyval and I'm pretty sure I'm doing it wrong because polyval is returning two numbers instead of three for each data set I'm trying to interpolate. Also, so far I've found lots of info on how to interpolate y, but I'm not sure how to interpolate x. Any help is greatly appreciated!
My data:
x = [10, 5, 2.5, 1.25, 0.625, 0.312, 0.156,0]
y = [41564.9, 21531.9, 15086.9, 9249, 3175.9, 1781.9, 1320.9, 182.9]
p = polyfit(x,y,1)
%Data set 1
%x1 = interpolated data
y1 = [609.9, 1085.9, 2157.9]
x1 = polyval(y1,p)
%Data set 2
%x2 = interpolated data
y2 = [1308.9, 2514.9, 4797.9]
x2 = polyval(y2,p)

 Accepted Answer

It is best to use one of the interpolation functions to do what you want.
Use interp1 here:
x = [10, 5, 2.5, 1.25, 0.625, 0.312, 0.156,0];
y = [41564.9, 21531.9, 15086.9, 9249, 3175.9, 1781.9, 1320.9, 182.9];
y2 = [1308.9, 2514.9, 4797.9];
x2 = interp1(y, x, y2, 'linear');
figure(1)
plot(x, y, '-g')
hold on
plot(x2, y2, 'bp')
hold off
grid
legend('Data', 'Interpolated Points', 'Location', 'NW')
To interpolate ‘x2’ from ‘y2’, reverse the usual (x,y) argument order, and use (y,x) instead, as I did here. The plot shows your original data as a green line, and the interpolated points as blue stars.

8 Comments

Thanks! Is there a way to make sure the interpolated data is on the best fit line?
My pleasure!
You can interpolate using methods other than 'linear', if that is what you mean. Otherwise, it depends on how you define the ‘best fit line’. A linear regression such as y = m*x + b you could easily invert to find values for x, for instance, x = (y-b)/m. For higher-degree polynomials, that would be more difficult, because for instance y = a*x^2 + b*x + c would produce two roots (values for x):
x(1) = -(b - (b^2 - 4*a*c + 4*a*y)^(1/2))/(2*a)
x(2) = -(b + (b^2 - 4*a*c + 4*a*y)^(1/2))/(2*a)
and higher order polynomials would have proportionally more possible roots. You could solve for them using fzero and other optimisation functions:
x2 = fzero(@(x) a*x.^3 + b*x.^2 + c*x + d - y2, -100)
but you would have to know an approximate starting value. There is also no guarantee that the result would not be complex. Using the roots function on a polynomial vector such as polyfit produces (and using the same notation): x2 = roots([a b c d-y2]) is another option.
So for simplicity, I would use interp1 on your actual data.
You could certainly calculate a range of y values for your ‘best fit line’ and use interp1 on it as I have on your original data here. That is significantly easier than attempting to invert it, and will give you a result that will be on your ‘best fit line’. Note that using the 'spline' method may be preferable in some situations than 'linear'.
These are my views. There are likely different valid approaches that others may share here.
What you said makes a lot of sense.
I am doing just a simple linear fit, I used lsline. What you've suggested works, it did get the interpolated points to show up. I think there should be just a small tweak to allow me to have the interpolated points on the least square fit line, would you know how to do that? Basically, the red and green markers show my interpolated data and I want to move these points vertically to be located on the linear fit line. Is there a way to do that?
Thank you.
I cannot recommend what you are doing, but if you want to find the y-values on the regression line for the x2 values you found from the interpolation, this will work:
x = 0 : 0.5 : 10; % Created Data
y = 2*x + 1 + 0.5*randn(size(x)); % Created Data
figure(1)
scatter(x, y)
lh = lsline; % Get ‘lsline’ Handle
glhx = get(lh,'XData'); % Get ‘lsline’ X
glhy = get(lh,'YData'); % Get ‘lsline’ Y
Lp = polyfit(glhx, glhy, 1); % Regenerate ‘lsline’ Parameters
x2 = 10*rand(1,5); % Data: ‘x2’
y2 = polyval(Lp, x2); % Calculate ‘y2’
hold on
scatter(x2, y2, 'rp'); % Plot
hold off
You will have to adapt it to your existing code, but it should work without problems.
How could I get X values if my curve is:
x= [0 4 10 16 23 33 45 55 60 65 88 91 101];
y= [12 8 5 5 6 7 7 6 5 5 7 8 12];
xint = 0:1:101;
yinterpol =interp1(x,y,xint,'spline');
plot(x,y,'o',xint,yinterpol)
Since for a single 'y' value, correspond many 'x' valuestopoprofile.svg
Thanks in advance
Choose an appropriate range of ‘x’ and ‘y’ to interpolate over for each value of ‘y’ you want to use, and reverse the first two arguments to interp1.

Sign in to comment.

More Answers (1)

It's all explained in my demo, attached below the image.
You can see the red training data and the blue points are more, frequent "in between" interpolated points.

4 Comments

Thanks for the explanation! However, this only helps me interpolate y-values based on x-values. I need to do the reverse. Any advice?
you can interpolate y values from x values by using interp1(y,x,yq,'method') rather than interp1(x,y,xq,'method') as is standard
i want to interpolate y values from x values using interp1(y,x,y,'method') , it doesn't work
ennabih, prove it. Show your code where you prove that the y values are not interpolated. By the way, interp1(y,x,y,'method') would produce an x value at a certain y value, NOT a y value. The y value is the third input, so the x value is the output (interpolated value).

Sign in to comment.

Categories

Find more on Interpolation 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!