I have an issue with using evalin
within a function that is being called in the body of a parfor-loop
. The function looks as follow:
function returnData = extractFun(input)
% assign close price to function call
x = evalin('base','data');
% extract prices
returnData = x(input);
end
And the script calling the function looks like this:
% data-array = n-by-1 double
data = [1:1000]';
% loop and extract data
parfor i = 1:10
% n-by-1 cell array containing 1-by-x doubles
% doubles in var1 contain valid indicies for the data-variable
var1 = {[1:10]; [1:30]};
% perform cell-function since, cell2mat will not work due to
% inconsistent dimensions of the double arrays contained in the cells
extractData = cellfun(@returnData,var1,'UniformOutput',false);
% do something with extractData
end
When I run the script in a parfor
-loop, matlab throws an error, that the index exceeds the matrix dimensions, which must mean that the variable x
is empty (or not being evaluated correctly). The weird thing is, that when I run the loop as a normal for
-loop, everything works fine. I know about the transparency-issues with parfor
-loops, hence I put the evalin
into a separate function.
I would also be open to alternative solutions to my problem, which is extracting data from One data variable into a n-by-1 cell array as doubles
without the use of additional loops, as I am intending to run this loop with a very high number of iterations.
Can anyone help me out? Thanks!
evalin
and parfor
don't mix. Even if you run parfor
with a local pool, you want to think of the workers that run the loop iterations as completely separate processes. In other words, they have no visibility of your base workspace at all. evalin
is not allowed in the loop body for a reason; hiding it in a function doesn't change the fact that there is no variable data
in the local base workspace of the worker, which will make the statement fail.
It is not clear to me why you fear the loop so much in this context. First of all, it's no longer 2006, when loops were still pretty bad for you; there has been some work done optimizing Matlab. Second, your cellfun
call with evalin
is a fairly inefficient way to simply read indices, and cellfun
doesn't do much more than hide a loop away. Third, you're planning to run parfor
here, which means that you may not be able to handle the likely higher memory usage coming from a fully vectorized loop replacement.
Consequently, just replace the cellfun
-call with
extractData = cell(size(var));
for iVar = 1:numel(var)
extractData{iVar} = data(var{iVar});
end