How to improve matrix indexing efficiency or avoid indexing in Finite difference?

11 views (last 30 days)
Hi all,
I am trying to optimize the performance of a FDTD (Finite-differnce-time-domain) code implemented in Matlab. As you may know, FDTD usually uses finite difference stencils in a time loop, i.e., the code calculates for example A(2:end,:)-A(1:end-1,:) many places in it. I've found that most of the time Matlab is spending on is not the actual subtracting or adding numbers, but the indexing.
For a very simple example, if I run this:
clear;
clc;
close all;
N1=100;
N2=100;
A=(ones(N1,N2,'single'));
C=(ones(N1,N2,'single'));
tic;
for i=1:1e4
%C(2:end,:)=C(2:end,:)-A(1:end-1,:);
C=C-A;
end
toc;
I got Elapsed time is 0.056711 seconds.
Instead if I run the following:
clear;
clc;
close all;
N1=100;
N2=100;
A=(ones(N1,N2,'single'));
C=(ones(N1,N2,'single'));
tic;
for i=1:1e4
C(2:end,:)=C(2:end,:)-A(1:end-1,:);
%C=C-A;
end
toc;
I got: Elapsed time is 0.316735 seconds.
That is to say the most of the time Matlab is just doing the matrix indexing, Is there any way to improve this or avoid the indexing but get the same result? This could make my code almost 10 times faster!

Accepted Answer

Matt J
Matt J on 18 Apr 2018
Edited: Matt J on 18 Apr 2018

the code calculates for example A(2:end,:)-A(1:end-1,:) many places in it.

For simple cases like this, you should be using the built-in DIFF command,

    D=diff(A,1,1); %equivalent to A(2:end,:)-A(1:end-1,:)

That is to say the most of the time Matlab is just doing the matrix indexing

It is not the indexing itself that is slow. It is that the indexing statements on the right hand side result in the creation of temporary arrays. Indexing on the left hand side should not have this problem, e.g., something like,

for i=1:1e4
    C(2:end,:)=X-Y; 
end

You can work around this this by doing right-hand side indexing outside of the loop, so that temporary arrays will be created only once:

tic;
Ctmp=C(2:end,:); Atmp=A(1:end-1,:);
for i=1:1e4
  Ctmp=Ctmp-Atmp;
end
C(2:end,:)=Ctmp; A(1:end-1,:)=Atmp;
toc

If you have more complicated indexing that varies from iteration to iteration of the loop, you could also try this FEX file, although I haven't used it myself.

  3 Comments

Sign in to comment.

More Answers (0)

Categories

Find more on Resizing and Reshaping Matrices in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!