2d grid interpolation to receive x-value
5 次查看(过去 30 天)
显示 更早的评论
Hello, I have a 2D-Grid. Assuming:
x=[0:0.05:0.5]
y=[0:5:20]
The grid is filled with a 5x11 DataSet, which contains random data (call it data).
Now I could interpolate using
interp2(x,y,data,x_i,y_i)
To receive the corresponding interpolated value to [x_i, y_i] from my dataSet.
What I need to do, is to interpolate an x value by passing y_i and a dataPoint from my dataset.
Something like:
[x_i]=interp2(y,data,y_i,data(j,k))
i,j,k const.
Thanks in advance!
回答(2 个)
KSSV
2018-5-17
YOu should use scatteredInterpolant for this case. How about this?
x=[0:0.05:0.5]
y=[0:5:20] ;
data = rand(length(y),length(x)) ;
[X,Y] = meshgrid(x,y) ;
F = scatteredInterpolant(Y(:),data(:),X(:)) ;
iwant = F(Y(1,7),rand(1,7))
3 个评论
John D'Errico
2018-5-17
There are serious potential problems here, ones that may not be solved using scatteredInterpolant as KSSV suggests.
Lets look at what you are trying to do, using some random data.
x = [0:0.05:0.5];
y = [0:5:20];
data = rand(numel(y),numel(x));
data
data =
0.49836 0.75127 0.95929 0.84072 0.34998 0.35166 0.28584 0.075854 0.12991 0.16218 0.60198
0.95974 0.2551 0.54722 0.25428 0.1966 0.83083 0.7572 0.05395 0.56882 0.79428 0.26297
0.34039 0.50596 0.13862 0.81428 0.25108 0.58526 0.75373 0.5308 0.46939 0.31122 0.65408
0.58527 0.69908 0.14929 0.24352 0.61604 0.54972 0.38045 0.77917 0.011902 0.52853 0.68921
0.22381 0.8909 0.25751 0.92926 0.47329 0.91719 0.56782 0.93401 0.33712 0.16565 0.74815
Yeah, I know, not very creative. But it is early in the morning for me, and you did not give us much to go on. And your data surely has SOME structure to it.
Now, let me pick a value for y to use here. We can think of this problem as a reverse interpolation at a specific y. I'll pick the value for y as 17.
yi = 17;
What does this surface look like along the line when y is fixed at 17? INTERP2 will give us that.
datapred = interp2(X,Y,data,x,repmat(yi,size(x)))
datapred =
0.44069 0.77581 0.19258 0.51782 0.55894 0.69671 0.4554 0.8411 0.14199 0.38338 0.71279
plot(x,datapred,'bx-')
grid on
xlabel x
ylabel 'data @ yi == 17'

Now, if you pick any given value of data, can you infer the value of x that produced it? Can you use reverse interpolation to infer x now? BE VERY CAREFUL HERE!
One thing you CANNOT do is simply swap the axes, and try to use an interpolant!!!!!!!
Thus, at datapred of 0.61604 (which lived at data(4,5) in my random set), for example, what value of x would we predict?
H = refline(0,data(4,5));set(H,'color','r')

So there are actually 7 locations where the red and blue lines intersect. That happens because our data was purely random. If the surface was nice and smooth and monotonic, things would be a bit better. There might be a unique solution then. But even so, the use of scatteredInterpolant as suggested by KSSV will be a problem.
When you use this form for scatteredInterpolant, what happens?
F = scatteredInterpolant(Y(:),data(:),X(:));
ezsurf(@(u,v) F(u,v),[min(y),max(y),0,1])

F(yi,data(4,5))
ans =
0.31909
So this gives ONE solution. But remember, there were 7 possible solutions. The function handle returned by scatteredInterpolant just gives one number. To be honest, I'm not even positive I can trust that one number that was returned.
plot(x,datapred,'bx-')
H = refline(0,data(4,5));set(H,'color','g')
hold on
plot(F(yi,data(4,5)),data(4,5),'ro')

In fact, the red dot there is not exactly on the blue curve. There is a slight error because the scattered interpolant is doing a 2-d interpolation, whereas the blue curve was created in a subtly different way.
Again, you cannot just swap the variables in an interpolation problem. The result will be random and sometimes significantly so.
John D'Errico
2018-5-17
编辑:John D'Errico
2018-5-17
There are serious potential problems here, ones that may not be solved using scatteredInterpolant as KSSV suggests.
Lets look at what you are trying to do, using some random data.
x = [0:0.05:0.5];
y = [0:5:20];
data = rand(numel(y),numel(x));
data
data =
0.49836 0.75127 0.95929 0.84072 0.34998 0.35166 0.28584 0.075854 0.12991 0.16218 0.60198
0.95974 0.2551 0.54722 0.25428 0.1966 0.83083 0.7572 0.05395 0.56882 0.79428 0.26297
0.34039 0.50596 0.13862 0.81428 0.25108 0.58526 0.75373 0.5308 0.46939 0.31122 0.65408
0.58527 0.69908 0.14929 0.24352 0.61604 0.54972 0.38045 0.77917 0.011902 0.52853 0.68921
0.22381 0.8909 0.25751 0.92926 0.47329 0.91719 0.56782 0.93401 0.33712 0.16565 0.74815
Yeah, I know, not very creative. But it is early in the morning for me, and you did not give us much to go on. And your data surely has SOME structure to it.
Now, let me pick a value for y to use here. We can think of this problem as a reverse interpolation at a specific y. I'll pick the value for y as 17.
yi = 17;
What does this surface look like along the line when y is fixed at 17? INTERP2 will give us that.
datapred = interp2(X,Y,data,x,repmat(yi,size(x)))
datapred =
0.44069 0.77581 0.19258 0.51782 0.55894 0.69671 0.4554 0.8411 0.14199 0.38338 0.71279
plot(x,datapred,'bx-')
grid on
xlabel x
ylabel 'data @ yi == 17'

Now, if you pick any given value of data, can you infer the value of x that produced it? Can you use reverse interpolation to infer x now? BE VERY CAREFUL HERE!
One thing you CANNOT do is simply swap the axes, and try to use an interpolant!!!!!!!
Thus, at datapred of 0.61604 (which lived at data(4,5) in my random set), for example, what value of x would we predict?
H = refline(0,data(4,5));set(H,'color','r')

So there are actually 7 locations where the red and blue lines intersect. That happens because our data was purely random. If the surface was nice and smooth and monotonic, things would be a bit better. There might be a unique solution then. But even so, the use of scatteredInterpolant as suggested by KSSV will be a problem.
How can we solve this, in a way that will always work, for any data? You need to recognize there may be multiple solutions.
A nice way, that will be robust and return all possible solutions in the event that multiple solutions do exist, is Doug Schwarz's intersections utility. You can download it from the file exchange from this link:
xi = intersections(x,datapred,[min(x),max(x)],repmat(data(4,5),1,2))
xi =
0.026164
0.063696
0.22072
0.26671
0.32083
0.3661
0.48532
As you can see, it found all 7 possible solutions.
plot(x,datapred,'bx-')
H = refline(0,data(4,5));set(H,'color','g')
hold on
plot(xi,data(4,5),'ro')

If data is a much more well-behaved, essentially monotonic surface, then intersections will still work, and usually produce one value. (Monotonicity is a concept that must be defined very carefully in multiple dimensions.)
2 个评论
John D'Errico
2018-5-17
But is that not exactly what I showed you how to solve?
If your surface is a smooth, well-behaved one, then you will see one solution, if any solution exists. So what is the question here? I gave you exactly the solution you wanted.
1. Use interp2 to generate a set of interpolations at yi.
2. Then use intersections to solve for xi.
Do you really desperately need a way in ONE line of code instead of two simple lines? Sigh. I'll need to create a more well-behaved surface.
x = [0:0.05:0.5];
y = [0:5:20];
data = exp(x + y'/20);
That example surface presumes your version of MATLAB is reasonably current.
yi = 17;
xi = fzero(@(u) interp2(x,y,data,u,yi) - data(4,5),[min(x),max(x)]);
xi =
0.0922306852282017
exp(xi + yi/20)
ans =
2.56569830498033
interp2(x,y,data,xi,yi)
ans =
2.58570965931585
data(4,5)
ans =
2.58570965931585
Did it work? Yes. But you need to recognize that if there happen to be multiple solutions, then fzero will NOT return all of them. You will arbitrarily get at most one of them, and it may indeed fail.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Logical 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!