【问题标题】:matlab using evalin in parformatlab在parfor中使用evalin
【发布时间】:2016-10-23 23:01:15
【问题描述】:

parfor-loop 的主体中调用的函数中使用evalin 时遇到问题。函数如下:

function returnData = extractFun(input)

    % assign close price to function call
    x = evalin('base','data');

    % extract prices
    returnData = x(input);

end

调用函数的脚本如下所示:

% 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

当我在 parfor-loop 中运行脚本时,matlab 会抛出一个错误,即索引超出了矩阵维度,这一定意味着变量 x 为空(或未正确评估)。奇怪的是,当我以正常的for-loop 运行循环时,一切正常。我知道parfor-loops 的透明度问题,因此我将evalin 放入一个单独的函数中。

我也愿意接受其他解决方案来解决我的问题,即在不使用额外循环的情况下,从 One 数据变量中提取数据到一个 n×1 元胞数组 doubles,因为我打算运行这个迭代次数非常多的循环。

谁能帮帮我?谢谢!

【问题讨论】:

    标签: matlab parfor


    【解决方案1】:

    evalinparfor 不要混用。即使您使用本地池运行parfor,您也希望将运行循环迭代的工作人员视为完全独立的进程。换句话说,他们根本看不到您的基础工作区。 evalin 不允许出现在循环体中,这是有原因的;将其隐藏在函数中并不会改变 worker 的本地基础工作区中没有变量 data 的事实,这会导致语句失败。

    我不清楚你为什么在这种情况下如此害怕循环。首先,它不再是 2006 年,那时循环对你来说仍然很糟糕;已经做了一些优化 Matlab 的工作。其次,使用evalin 调用cellfun 是一种效率很低的简单读取索引的方法,而cellfun 只不过是隐藏了一个循环而已。第三,您计划在此处运行 parfor,这意味着您可能无法处理来自完全矢量化循环替换的可能更高的内存使用量。

    因此,只需将 cellfun-call 替换为

    extractData = cell(size(var));
    for iVar = 1:numel(var)
        extractData{iVar} = data(var{iVar});
    end
    

    【讨论】:

    • 已选择使用此解决方案。你是对的 - 额外循环的额外处理时间并不像我想象的那么糟糕,并且几乎比 cellfun 快(很可能正如你所说,因为它实际上毕竟是一种循环)。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-22
    • 2020-05-22
    • 1970-01-01
    • 1970-01-01
    • 2011-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多