MATLAB Answers

EE
0

parfor and function call using scatteredInterpolant

Asked by EE
on 22 Oct 2019
Latest activity Answered by Edric Ellis
on 25 Oct 2019
First of all, note that I've read this: https://de.mathworks.com/matlabcentral/answers/471133-can-we-use-scatteredinterpolant-in-parallel but it doesn't help me...
My script looks something like this:
function main
global myinterp
d=dlmread('data.txt');
x=d(:,1);
y=d(:,2);
z=d(:,3);
myinterp=scatteredInterpolant(x,y,z);
parfor i=1:length(x)
tmp=myfun(x(i),y(i));
end
end
function result=myfun(x,y)
global myinterp
result=interp(x,y);
end
Of course this doesn't work and gives an Error: Subscript indices must either be real positive integers or logicals
However, if I impicitly define the function before the parfor loop as
...
myfun=@(x,y) myinterp(x,y);
parfor i=1:length(x)
tmp=myfun(x(i),y(i));
end
...
everything works fine.
Unfortunately my actual function looks far more complicated and it would be kind of messy to write the function (and all the other functions it calls) implicitly.
Is there any way to make my 1st example work? I believe I would have to pass the interpolation handle as an additional parameter somehow and evaluate it. But I wasn't able to find an evaluation method for the "scatteredInterpolant" - object.
Any suggestions?
EDIT: I found a workaround I guess by simply passing the interpolation object as an additional parameter. However, I'm not sure if this is really the best way to achieve this regarding communication of data. Ideally the interpolation object is broadcasted only once, but is matlab smart enough to recognize that its a constant quantitiy and doesn't need to be communicated every iteration?

  0 Comments

Sign in to comment.

1 Answer

Answer by Edric Ellis
on 25 Oct 2019
 Accepted Answer

I'm not that familiar with scatteredInterpolant, but I concocted the following which shows I think the sort of thing you're after:
% Use scatteredInterpolant example from the documentation
t = linspace(3/4*pi,2*pi,50)';
x = [3*cos(t); 2*cos(t); 0.7*cos(t)];
y = [3*sin(t); 2*sin(t); 0.7*sin(t)];
v = repelem([-0.5; 1.5; 2],length(t));
F = scatteredInterpolant(x,y,v);
% Make a parallel.pool.Constant from 'F'
Fc = parallel.pool.Constant(F);
% Use 'Fc' inside parfor
tq = linspace(3/4*pi+0.2,2*pi-0.2,40)';
parfor idx = 1:numel(tq)
thisTq = tq(idx);
xq(idx) = 2.8*cos(thisTq);
yq(idx) = 2.8*sin(thisTq);
vq(idx) = useInterpolant(Fc.Value, xq(idx), yq(idx));
end
% Evaluate the scatteredInterpolant
function z = useInterpolant(F, x, y)
z = F(x,y);
end
Note that the use of parallel.pool.Constant is only required if you're going to use the same large value in multiple parfor loops. parfor is already smart enough not to copy "broadcast" variables more than necessary for a single loop.

  0 Comments

Sign in to comment.