フィルターのクリア

2-D Bilinear interpolation

141 ビュー (過去 30 日間)
Nimananda Sharma
Nimananda Sharma 2019 年 1 月 30 日
コメント済み: Matt J 2024 年 6 月 13 日
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.

採用された回答

Matt J
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 件のコメント
Nimananda Sharma
Nimananda Sharma 2019 年 2 月 1 日
Thanks Matt. I have decided now to use a combination of griddedInterpolant for scalar qwery points and inter2 with gpuArray for qwery points which are double. I still managed to get 40% boost in computational efficiency. At this moment, I think I will live with it. Thanks a lot for your inputs.

サインインしてコメントする。

その他の回答 (1 件)

Matt J
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
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
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 ExchangeGPU Computing in MATLAB についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by