Faster interpolation than interp2 ?

32 views (last 30 days)
H ZETT M
H ZETT M on 5 Dec 2016
Commented: Guillaume on 6 Dec 2016
Hey guys, I have a question. I am currently using interp2 for interpolation of single points on a grid. In my case it is
if true
k1u=interp2(lat,lon,u_now_flow,b,a)
end
So lat and lon are the sample grid points (this is how matlab calls it. they get created by meshgrid), u_now_flow is a flow field and b and a are vectors which look like this:
53.9603
53.9603
53.9603
53.9703
53.9703
53.9703
53.9803
53.9803
53.9803
54.0003
so the code is working fine, but I wanted to know if there are faster ways/functions to interpolate the points on a grid. I tried to use griddedInterpolant, but failed cause I always got NaN, but I have no idea why. I hope you can help me

Accepted Answer

Guillaume
Guillaume on 5 Dec 2016
griddedInterpolant may be marginally faster than interp2 since interp2 does a little bit of argument manipulation before finally using griddedInterpolant to do the heavy work. I wouldn't expect the difference to be significant enough that it'd matter.
There are no other interpolating methods in matlab that are faster.
Using griddedInterpolant, your code should be:
ginterp = griddedInterpolant(lat, lon, u_now);
k1u = ginterp(a, b); %assuming a and b are vectors of the same length and shape.
  2 Comments
H ZETT M
H ZETT M on 6 Dec 2016
Edited: H ZETT M on 6 Dec 2016
Thank you for the reply. Would you mind to help me getting griddedInterpolant working ?
I will try to provide as many information as possible. So I get lat and lon from my data. They look like this:
lat =
54.37500
54.32500
54.27500
54.22500
54.17500
.........
lon = 5.041700
5.125000
5.208300
5.291700
5.375000
.........
lon is 37x1 and lat is 23x1. after this I use meshgrid which makes these vectors 37x23.
I also get from my Data the velocity field u and v, which are 37x23x1056.
With interp2 I can now do the interpolation. If x_old and y_old are the old positions of my particle on the grid, and u_now_flow is the flow field at the current time the code looks like this:
k1u=interp2(lat,lon,u_now_flow,y_old,x_old);
This works. (I have no clue if in the following parts in matters that I have an old matlab version (2011) here at work).
The matlab documentation says:
To convert X, Y, and V to ndgrid format, follow these steps:
Transpose each array in the grid as well as the sample data.
X=X';
Y=Y';
V=V';
So what I did now is
lat = lat';
lon = lon';
u_now_flow = u_now_flow';
Now lon and lat are 23x37, just like u_now_flow. If I use now
F = griddedInterpolant(lat,lon,u_now_flow)
I get the error message " Error using griddedInterpolant The grid was created from grid vectors that were not strictly monotonic increasing."
I think this might be due to the fact that the original lat (at the beginning) is decreasing. So I sorted lat that it is now ascending (is it the right word ?). Next I used meshgrid again and also did the transposing. lat lon is now again 37x23 (since I just changed the order of lat).
If I now just F again it is working (I do not get any error messages). But If I use now F(x_old,y_old) which would be in this case F(7.7076,53.9603). I get NaN. My F.Value looks like in the picture attached and is the same as my u_flow.
Do you have any idea what exactly the problem is ?
Edit: I should try to explain better what exactly I try to do. I want to interpolate my flow field at the point of my particle x_old/y_old in a grid, which is based on lat/lon (this is why I have F(7.7076,53.9603)).
Guillaume
Guillaume on 6 Dec 2016
I'm not sure what that discussion in the doc of griddedInterpolant about meshgrid vs ndgrid is about. I doesn't matter which you use to generate the grid, as long as it's consistent with the data. In any case, i would always use ndgrid since it does not mix up two different coordinates systems.
Your first issue is indeed with the fact that your lat vector is strictly monotically decreasing instead of strictly monotically increasing. That is easily fixed, flip it up/down and, of course, do the same with the velocity map.
lat = flipud(lat);
u_now_flow = flipud(u_now_flow); %to reflect the ordering change on lat
Now, you can ndgrid your latitude, longitude and pass that to griddedInterpolant, if you wish:
[glat, glon] = ndgrid(lat, lon); %after lat has been flipped
interpolant = griddedInterpolant(glat, glon, u_now_flow); %after u_now_flow has been flipped
but you don't even need to grid the coordinates, if you use this syntax:
interpolant = griddedInterpolant({lat, lon}, u_now_flow); %after flipping
Demo code:
lat = (54.375 - (0:36)*0.05) .'
lon = (5.0417 + (0:22)*0.0533) .'
u_now_flow = exp(-bsxfun(@plus, (lat - 53.5).^2, (lon.' - 6).^2)); %nice surface for demo
interpolant = griddedInterpolant({flipud(lat), lon), flipud(u_now_flow));
interpolant(53.9603, 7.7076)
Note the order of inputs for the interpolant is latitude, longitude. Otherwise of course you get NaN since the coordinates are outside the grid.

Sign in to comment.

More Answers (0)

Categories

Find more on Interpolation in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!