2-D Bilinear interpolation (2024)

112 views (last 30 days)

Show older comments

Nimananda Sharma on 30 Jan 2019

  • Link

    Direct link to this question

    https://www-ah.mathworks.com/matlabcentral/answers/442274-2-d-bilinear-interpolation

  • Link

    Direct link to this question

    https://www-ah.mathworks.com/matlabcentral/answers/442274-2-d-bilinear-interpolation

Commented: Matt J on 13 Jun 2024 at 10:40

Accepted Answer: Matt J

Open in MATLAB Online

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 Comments

Show -2 older commentsHide -2 older comments

Sign in to comment.

Sign in to answer this question.

Accepted Answer

Matt J on 31 Jan 2019

  • Link

    Direct link to this answer

    https://www-ah.mathworks.com/matlabcentral/answers/442274-2-d-bilinear-interpolation#answer_358897

  • Link

    Direct link to this answer

    https://www-ah.mathworks.com/matlabcentral/answers/442274-2-d-bilinear-interpolation#answer_358897

Edited: Matt J on 31 Jan 2019

Open in MATLAB Online

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 Comment

Show -1 older commentsHide -1 older comments

Nimananda Sharma on 1 Feb 2019

Direct link to this comment

https://www-ah.mathworks.com/matlabcentral/answers/442274-2-d-bilinear-interpolation#comment_666619

  • Link

    Direct link to this comment

    https://www-ah.mathworks.com/matlabcentral/answers/442274-2-d-bilinear-interpolation#comment_666619

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.

Sign in to comment.

More Answers (1)

Matt J on 30 Jan 2019

  • Link

    Direct link to this answer

    https://www-ah.mathworks.com/matlabcentral/answers/442274-2-d-bilinear-interpolation#answer_358720

  • Link

    Direct link to this answer

    https://www-ah.mathworks.com/matlabcentral/answers/442274-2-d-bilinear-interpolation#answer_358720

Edited: Matt J on 30 Jan 2019

Open in MATLAB Online

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 Comments

Show 6 older commentsHide 6 older comments

Nimananda Sharma on 31 Jan 2019

Direct link to this comment

https://www-ah.mathworks.com/matlabcentral/answers/442274-2-d-bilinear-interpolation#comment_666141

  • Link

    Direct link to this comment

    https://www-ah.mathworks.com/matlabcentral/answers/442274-2-d-bilinear-interpolation#comment_666141

Open in MATLAB Online

Thanks Matt J for the input. I tried discretize and now I can use for scalar and non scalar inputs.

May be you are right, the griddedInterpolant is still 5 times faster. Do you think converting my m-code to MEX file will help achieve faster computation? The interpolation operation is used in a larger simulation which runs multiple serial iterations as in iterations itself can't be vectorize. And computationally, the most time consuming part is interpolation.

% Calculate upper and lower bound in x direction

idx1 = discretize(x,X(:,1),'IncludedEdge','right'); idx2 = idx1 + 1;

% Calculate upper and lower bound in y direction

idy1 = discretize(y,Y(1,:),'IncludedEdge','right'); idy2 = idy1 + 1;

Direct link to this comment

https://www-ah.mathworks.com/matlabcentral/answers/442274-2-d-bilinear-interpolation#comment_666225

  • Link

    Direct link to this comment

    https://www-ah.mathworks.com/matlabcentral/answers/442274-2-d-bilinear-interpolation#comment_666225

Edited: Matt J on 31 Jan 2019

griddedInterpolant is already MEX driven.

Do you have the Parallel Computing Toolbox and a strong GPU? If so, you could covert your data to gpuArrays and use interp2.

Nimananda Sharma on 31 Jan 2019

Direct link to this comment

https://www-ah.mathworks.com/matlabcentral/answers/442274-2-d-bilinear-interpolation#comment_666233

  • Link

    Direct link to this comment

    https://www-ah.mathworks.com/matlabcentral/answers/442274-2-d-bilinear-interpolation#comment_666233

Open in MATLAB Online

Using histcount instead of discretize improves the speed. Computation is slightly faster than griddedinterpolant. Yes, I have the parallel computing toolbox. I have NVIDIA Quadro K420 GPU with 1 GB memory. Now, I am trying to use directly the MEX files insteading of calling the functions to save time from function overhead. I can also try gpuArrays. However, I have found that interp2 is 50 times slower than griddedInterpolant when griddedInterpolant is created before the simulation. I also tried converting my interpolation code with hiscounts as follows to MEX file. However, the computation was slower than using m-file. Here is the funtion, I am using right now

function [v] = interp2D(X, Y, V, x , y)

% Calculate upper and lower bound in x direction

[~ , ~, idx1] = histcounts(x, X(:,1));

idx1(end,:) = idx1(end,:)+1;

idx2 = idx1 - ones(size(idx1));

% Calculate upper and lower bound in y direction

[~ , ~, idy1] = histcounts(y,Y(1,:));

idy1(:,end) = idy1(:,end)+1;

idy2 = idy1 - ones(size(idy1));

% Evaluate the function at four points

V11 = V(idx1(1): idx1(end), idy1(1): idy1(end));

V12 = V(idx1(1): idx1(end), idy2(1): idy2(end));

V21 = V(idx2(1): idx2(end), idy1(1): idy1(end));

V22 = V(idx2(1): idx2(end), idy2(1): idy2(end));

x1 = X(idx1(1): idx1(end) , 1);

x2 = X(idx2(1): idx2(end) , 1);

y1 = Y(1 , idy1(1): idy1(end));

y2 = Y(1 , idy2(1): idy2(end));

% Interpolate in x-direction

Vx1 = (x2 - x) .* V11 ./ ( x2 - x1) + (x - x1) .* V21 ./( x2 - x1);

Vx2 = (x2 - x) .* V12 ./ ( x2 - x1) + (x - x1) .* V22 ./ ( x2 - x1);

% Interpolate in y-direction

v = (y2 - y) .* Vx1 ./(y2 - y1) + (y - y1) .* Vx2 ./(y2 - y1);

Matt J on 31 Jan 2019

Direct link to this comment

https://www-ah.mathworks.com/matlabcentral/answers/442274-2-d-bilinear-interpolation#comment_666240

  • Link

    Direct link to this comment

    https://www-ah.mathworks.com/matlabcentral/answers/442274-2-d-bilinear-interpolation#comment_666240

Edited: Matt J on 31 Jan 2019

gpuArrays have a different implementation of interp2 than the one you‘ve tried. In all likelihood, it uses GPU texture memory and so should be much faster.

Nimananda Sharma on 31 Jan 2019

Direct link to this comment

https://www-ah.mathworks.com/matlabcentral/answers/442274-2-d-bilinear-interpolation#comment_666241

  • Link

    Direct link to this comment

    https://www-ah.mathworks.com/matlabcentral/answers/442274-2-d-bilinear-interpolation#comment_666241

The comparision between interp2 and griddedinterpolant is here as well. Scroll to the bottom of the page.

Matt J on 31 Jan 2019

Direct link to this comment

https://www-ah.mathworks.com/matlabcentral/answers/442274-2-d-bilinear-interpolation#comment_666301

  • Link

    Direct link to this comment

    https://www-ah.mathworks.com/matlabcentral/answers/442274-2-d-bilinear-interpolation#comment_666301

Edited: Matt J on 31 Jan 2019

Again, irrelevant for the GPU. However, you will probably need something stronger than the Quadro K420.

Sean Sullivan on 11 Jun 2024 at 13:03

Direct link to this comment

https://www-ah.mathworks.com/matlabcentral/answers/442274-2-d-bilinear-interpolation#comment_3184041

  • Link

    Direct link to this comment

    https://www-ah.mathworks.com/matlabcentral/answers/442274-2-d-bilinear-interpolation#comment_3184041

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 on 13 Jun 2024 at 10:40

Direct link to this comment

https://www-ah.mathworks.com/matlabcentral/answers/442274-2-d-bilinear-interpolation#comment_3185761

  • Link

    Direct link to this comment

    https://www-ah.mathworks.com/matlabcentral/answers/442274-2-d-bilinear-interpolation#comment_3185761

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).

Sign in to comment.

Sign in to answer this question.

See Also

Categories

Parallel ComputingParallel Computing ToolboxGPU ComputingGPU Computing in MATLAB

Find more on GPU Computing in MATLAB in Help Center and File Exchange

Tags

  • bilinear interpolation
  • 2-d
  • griddedinterpolant
  • gpuarray
  • interp2
  • interpolation

Products

  • Parallel Computing Toolbox

Community Treasure Hunt

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

Start Hunting!

An Error Occurred

Unable to complete the action because of changes made to the page. Reload the page to see its updated state.


2-D Bilinear interpolation (13)

Select a Web Site

Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .

You can also select a web site from the following list

Americas

  • América Latina (Español)
  • Canada (English)
  • United States (English)

Europe

  • Belgium (English)
  • Denmark (English)
  • Deutschland (Deutsch)
  • España (Español)
  • Finland (English)
  • France (Français)
  • Ireland (English)
  • Italia (Italiano)
  • Luxembourg (English)
  • Netherlands (English)
  • Norway (English)
  • Österreich (Deutsch)
  • Portugal (English)
  • Sweden (English)
  • Switzerland
    • Deutsch
    • English
    • Français
  • United Kingdom(English)

Asia Pacific

Contact your local office

2-D Bilinear interpolation (2024)
Top Articles
Latest Posts
Article information

Author: Ray Christiansen

Last Updated:

Views: 6582

Rating: 4.9 / 5 (69 voted)

Reviews: 92% of readers found this page helpful

Author information

Name: Ray Christiansen

Birthday: 1998-05-04

Address: Apt. 814 34339 Sauer Islands, Hirtheville, GA 02446-8771

Phone: +337636892828

Job: Lead Hospitality Designer

Hobby: Urban exploration, Tai chi, Lockpicking, Fashion, Gunsmithing, Pottery, Geocaching

Introduction: My name is Ray Christiansen, I am a fair, good, cute, gentle, vast, glamorous, excited person who loves writing and wants to share my knowledge and understanding with you.