2016-11-25 47 views
1

我具有矩阵如何在单元格数组中向量化调用函数?

x = rand(10,100,3); 

和一个功能单元阵列:伪代码是

funcca = {... 
    @(v)(v(1)+v(2)), @(v)(v(1)-v(2)), ......, @(v)(v(1)+v(2)+v(3)^2); 
    ⋮ 
    ⋮ 
    @(v)(v(1)^6+sqrt(v(3))), @(v)(sin(v(1))-cos(v(2))),......,@(v)(v(1)) 
}; 

其中size(funcca) = [10, 100]。这意味着funcca中的每个功能都不相同!

现在我用下面的代码来计算y

y = nan(10,100); 
for i = 1 :10 
    for j = 1:100 
     y(i,j) = funcca{i,j}(squeeze(x(i,j,:))); 
    end 
end 

有没有一种方法,我可以避开这个两个for环或矢量化这个过程?

+3

松散地说,矢量化是关于将数组输入的每个元素的函数的多个调用转换为整个数组的单个调用。但这里的问题是调用1000个不同的函数而不是循环,所以没有地方进行矢量化。 – rahnema1

+1

你的功能必须是矢量化的,而不是你称之为的方式。 –

+0

我认为你的主要性能问题是循环内部的'挤压';这不是一个MATLAB内置的,也就是说,JIT不能编译它,你会得到糟糕的性能。只需在循环前执行'permute'并调整循环内的提取索引,这应该可以显着改善事情。 –

回答

0

matlab函数cellfun将允许您对单元格数组中的每个元素执行操作。在这种情况下:

y = cellfun(@(c)c(rand(1, 3)), funcca); 

,或者x实际上应该是明确的数据,并在你的问题不是随机产生的,然后像

y = cellfun(@(fh, data)fh(squeeze(data)), funcca, num2cell(x, 3)); 
+4

实际上cellfun并没有矢量化操作,这只是“一个隐藏的循环” – obchardon

+3

但它不再是你的错。现在是MathWorks的错误,因为没有矢量化cellfun –

+1

不需要“挤压”;通过它的外观,'funcca'明确地调用元素'1','2'和'3',你可以在1×1×3的数组中完成。 –

0

其实,调用cellfun应该是这样的:

z = cellfun(@(f,y) f(y), funcca, num2cell(x,3)); 

但是,正如obchardon所指出的那样,这实际上并没有给你加速。它只是为您节省一些打字。

其实,我认为这更多是一个设计问题 - 你是如何结束这一系列功能的?你能提供一些背景吗?

相关问题