如何使用 `cellfun` (MATLAB) 应用具有多个参数的函数?

How do I apply a function with multiple parameters using `cellfun` (MATLAB)?

如何使用 cellfun,将一个函数应用于 mat2cell 函数创建的所有单元格?我的函数定义在另一个文件中,这里用 myFunc 引用。此函数有两个参数,应该是一个单元格和一个整数。

例如function H = myFunc(img,Q)

我的代码如下:

% Split into grid and process each cell
width = size(img,2) % get image width
height = size(img,1) % get image height
depth = size(img,3) % get depth
C = mat2cell(img,[height/2 height/2],[width/2 width/2],[depth/2 depth/2]); % divides image into sections
F = cellfun(@myFunc,C);
save(fout,'F');

问题当然出在行 F = cellfun(@myFunc,C); 上。如何传递单元格和选定的整数,例如每个单元格 4 成 myFunc

非常感谢。

好吧,简单地定义一个新的匿名函数为@(x) myFunc(x,4)并这样使用它:

F = cellfun(@(x) myFunc(x,4), C)

通过使用匿名函数:

F = cellfun(@(Q) myFunc(Q,4),C);

最近遇到这个问题,注意到虽然 Octave 在 cellfun 中有参数的隐式单元扩展,但 Matlab 没有。调用匿名函数比直接调用函数有更多的开销(尽管 Matlab 在这方面不如 Octave 差)所以我发现将参数作为元胞数组传递要快一点,这里用一个简单的例子展示:

abc = {magic(2), magic(3), magic(4)}
abc =
  3×1 cell array
    {2×2 double}
    {3×3 double}
    {4×4 double}
    
def = cellfun (@(x) sum(x,2), abc, "UniformOutput", false) %anonymous function method
def =
  3×1 cell array
    {2×1 double}
    {3×1 double}
    {4×1 double}
def{:}
ans =
     4
     6
ans =
    15
    15
    15
ans =
    34
    34
    34
    34 

将参数扩展到元胞数组并将其作为另一个输入传递会产生相同的正确输出:

def = cellfun (@sum, abc, num2cell(2*ones(size(abc))), "UniformOutput", false) % cell expansion method
def =
  3×1 cell array
    {2×1 double}
    {3×1 double}
    {4×1 double}
def{:}
ans =
     4
     6
ans =
    15
    15
    15
ans =
    34
    34
    34
    34 
    

快速 tic/toc 检查表明这在 Matlab 2021a 中要快一些:

tic; 
for idx = 1:100000
  cellfun(@(x) sum(x,2), abc,"UniformOutput",false); 
end
toc
Elapsed time is 4.017116 seconds.

tic, 
for idx = 1:100000
  cellfun(@sum, abc, num2cell(2*ones(size(abc))),"UniformOutput",false);
end
toc
Elapsed time is 1.217712 seconds

我还没有用非简单参数尝试过这个,但是 repmat 可以对字符串输入做同样的事情,但是 repmat 似乎增加了相当多的开销:

tic
for idx = 1:100000
    cellfun(@sum, abc, repmat({2}, size(abc)),"UniformOutput",false); 
end
toc
Elapsed time is 4.367002 seconds.

所以也许有更好的方法来扩展它们。请注意,这是一个非常简单的测试用例,包含一个小数组,随着规模的扩大或您添加多个参数,这种时间节省可能并不适用。此外,您正在乘以执行此操作的每个参数的内存需求,因为每个参数都扩展到输入数组的大小。

快速测试表明,自定义 myfuncsum.

等 matlab 函数节省的时间相同