2-D Bilinear interpolation
94 次查看(过去 30 天)
显示 更早的评论
Hi,
I am trying to build a 2-D bilinear interpolation function as shown below. While using the profiler, I noticed that the maximum computation time is spent in finding upper and lower bound
temp = x(i,j) <= X;
[idx1, ~] = find(temp, 1);
x , y are scalars
and X, Y, V are gridded data with equal size of (m, n).
My aim is to achieve better computational performance than using the native griddedinterpolant in Matlab
V_fit = griddedInterpolant(X, Y, V, 'linear' )
v = V_fit (x, y)
At the moment, griddedinterpolant is 10 times faster than my user defined function.
Is there a better way to calculate the upper and lower bounds? Possibly, that works also when x , y are matrix of size (i,j).
function [v] = interp2D(X, Y, V, x, y)
% Calculate lower bound in x direction
temp = x <= X;
[idx1, ~] = find(temp, 1);
% Calculate upper bound in x direction
temp = x > X;
[idx2, ~] = find(temp, 1, 'last');
% Calculate lower bound in y direction
temp = y <= Y;
[~, idy1] = find(temp, 1);
% Calculate upper bound in y direction
temp = y > Y;
[~ , idy2] = find(temp, 1, 'last');
% Evaluate the function at four points
V11 = V(idx1 , idy1);
V12 = V(idx1 , idy2);
V21 = V(idx2 , idy1);
V22 = V(idx2 , idy2);
% Interpolate in x-direction
Vx1 = (X(idx2 , 1) - x) * V11 / ( X(idx2 , 1) - X(idx1 , 1)) + ...
(x - X(idx1 , 1)) * V21 / ( X(idx2, 1) - X(idx1, 1));
Vx2 = (X(idx2, 1) - x) * V12 / ( X(idx2, 1) - X(idx1, 1)) + ...
(x - X(idx1, 1)) * V22 / ( X(idx2, 1) - X(idx1, 1));
% Interpolate in y-direction
v = (Y(1, idy2) - y) * Vx1 / ( Y(1 , idy2) - Y(1, idy1)) + (y - Y(1, idy1)) * Vx2 / ( Y(1, idy2) - Y(1, idy1));
end
Edit: In my case, m = 181, n = 181. And, while comparing computational time, I assume that griddedInterpolant(X, Y, V, 'linear' ) is performed before the simulation is run i.e. I compare the time of v = V_fit (x, y) with the execution time of my code.
0 个评论
采纳的回答
Matt J
2019-1-31
编辑:Matt J
2019-1-31
Here is a race of griddedInterpolant on the CPU (AMD Ryzen Threadripper 1900X, 3850 Mhz) against gpuArray.interp2 on the GeForce GTX 1080 Ti. As you can see, the latter is almost 5 times faster. This was in R2018a.
dtype='single';
N=512;
V=rand(N,dtype);
x=randi([1,N], [1,N^3]);
y=randi([1,N], [1,N^3]);
%%%%%%%%%%% Using griddedInterpolant on the CPU %%%%%%%%%%%%
F=griddedInterpolant(V);
tic;
F(x,y);
toc
%Elapsed time is 0.567307 seconds.
%%%%%%%%%%% Using the GPU %%%%%%%%%%%%
gd=gpuDevice;
x=gpuArray(x);y=gpuArray(y); V=gpuArray(V);
tic;
interp2(V,x,y);
wait(gd)
toc;
%Elapsed time is 0.132149 seconds.
更多回答(1 个)
Matt J
2019-1-30
编辑:Matt J
2019-1-30
I don't think you're going to beat griddedInterpolant in M-code, but a better way of computing of the bounds (and one which works on non-scalars) is,
idx1=discretize(x,X); idx2=idx1+1;
idy1=discretize(y,Y); idy2=idy1+1;
8 个评论
Sean Sullivan
2024-6-11
As of R2023b, griddedInterpolant also supports gpuArray input.
When I run similar code to Matt J in R2024a, but time griddedInterpolant running on the GPU as well, I see very little difference between the performance of interp2 and griddedInterpolant.
Matt J
2024-6-13
As of R2023b, griddedInterpolant also supports gpuArray input.
Great news!! (Although, I hope we will eventually get the full complement of interpolation/extrapolation methods for 3D data).
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 GPU Computing in MATLAB 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!