Speeding up (vectorizing) barycentric interpolation
Show older comments
Dear All, I have the following problem:
is it possible to speed up the barycentric interpolation given below? I presume that vectorization could be particularly effective but I do not know how to do it. As the code has to be run many times (and the size of matrices involved is rather large) any increase in efficiency would be helpful. Could GPU computing, after vectorization, be of any help here?
na = 100;
nh = 100;
nm = 100;
nap = na+2;
nhp = nh+2;
H = randn(nap,nhp) ;
M = randn(nap,nhp) ;
MP = randn(nap,nhp) ;
ap_trial = NaN(nh,nm) ;
hp_trial = NaN(nh,nm) ;
mp_trial = NaN(nh,nm) ;
[h_grid,m_grid] = ndgrid(1:nh,1:nm);
[ap_grid,hp_grid] = ndgrid(1:nap,1:nhp);
tic
for r0 = 0:1
for r1 = 0:(nap-2)
for r2 = 0:(nhp-2) % loops picking up triangles constructed by adjacent points in matrices H and M
h1 = H(1+r1+r0,1+r2+r0);
h2 = H(1+r1,2+r2);
h3 = H(2+r1,1+r2);
m1 = M(1+r1+r0,1+r2+r0);
m2 = M(1+r1,2+r2);
m3 = M(2+r1,1+r2);
% barycentric interpolation (weights)
w1 = ( (m2-m3)*( h_grid -h3) + (h3-h2)*( m_grid -m3) ) / ( (m2-m3)*(h1-h3) + (h3-h2)*(m1-m3) );
w2 = ( (m3-m1)*( h_grid -h3) + (h1-h3)*( m_grid -m3) ) / ( (m2-m3)*(h1-h3) + (h3-h2)*(m1-m3) );
w3 = 1 - w1 - w2;
% preventing extrapolation
w1(w1 < 0) = NaN;
w2(w2 < 0) = NaN;
w3(w3 < 0) = NaN;
% barycentric interpolation (results)
ap = w1 * ap_grid(1+r1+r0,1+r2+r0) + w2 * ap_grid(1+r1,2+r2) + w3 * ap_grid(2+r1,1+r2);
hp = w1 * hp_grid(1+r1+r0,1+r2+r0) + w2 * hp_grid(1+r1,2+r2) + w3 * hp_grid(2+r1,1+r2);
mp = w1 * MP(1+r1+r0,1+r2+r0) + w2 * MP(1+r1,2+r2) + w3 * MP(2+r1,1+r2);
ap_trial( isnan(ap) == 0 ) = ap( isnan(ap) == 0 );
hp_trial( isnan(hp) == 0 ) = hp( isnan(hp) == 0 );
mp_trial( isnan(mp) == 0 ) = mp( isnan(mp) == 0 );
end
end
end
toc
14 Comments
per isakson
on 5 Apr 2020
Adam Pigon
on 5 Apr 2020
per isakson
on 5 Apr 2020
Edited: per isakson
on 6 Apr 2020
The tic toc made me ask.
I cannot see how to vectorize any part of your code. (But other might.)

It helps a tiny bit to replace isnan(ap) == 0 by ~isnan(ap), etc
These six red lines takes more than 80% of the time (on my system).
darova
on 6 Apr 2020
I added imagesc inside first for loop

Only a few elements is re-calculated all the time. Can you attach original data?
Adam Pigon
on 6 Apr 2020
darova
on 6 Apr 2020
On the animation matrix is hp_trial. I mean if you know that only a few elements (positions) re-calculated all the time you don't need these operations. Every cycle you are searching for NaN values (runs through entire matrix)
ap_trial( isnan(ap) == 0 ) = ap( isnan(ap) == 0 );
hp_trial( isnan(hp) == 0 ) = hp( isnan(hp) == 0 );
mp_trial( isnan(mp) == 0 ) = mp( isnan(mp) == 0 );
Maybe can be replaced with
ap1 = ap(1:5,1:5);
aptr1 = ap_trial(1:5,1:5);
aptr1( ~isnan(ap1) ) = ap1( ~isnan(ap1) ); % search only in up left corner
ap_trial(1:5,1:5) = aptr1;
- Original data will not help much I guess?
We will find out
Adam Pigon
on 8 Apr 2020
darova
on 8 Apr 2020
I tried to scale rand numbers by 15

Is this correct?

Adam Pigon
on 8 Apr 2020
darova
on 8 Apr 2020
Ok i understood. What about these? Those a values inside triangle too?
w1(w1 < 0) = NaN;
w2(w2 < 0) = NaN;
w3(w3 < 0) = NaN;
Adam Pigon
on 8 Apr 2020
darova
on 8 Apr 2020
Then you can use my brilliant idea again and search for NaN in triangle region

Adam Pigon
on 12 Apr 2020
darova
on 12 Apr 2020
Thanks for the link
Answers (0)
Categories
Find more on Logical 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!