具有不同维度输入的函数的arrayfun

Posted

技术标签:

【中文标题】具有不同维度输入的函数的arrayfun【英文标题】:arrayfun with function with inputs of different dimensions 【发布时间】:2014-04-17 06:20:47 【问题描述】:

我正在尝试创建一个矩阵,其中包含较大 nxn 矩阵的 kxk 个子矩阵的平均值,其中 n 可被 k 整除。我可以用这样的东西相当有效地完成这个

mat = mat2cell(mat, k*ones(1,n/k), k*ones(1,n/k))
mat = cellfun(@mean,mat,'UniformOutput',false);
mat = cellfun(@mean,mat,'UniformOutput',false); %repeated to collapse cells to 1x1
mat = cell2mat(mat)

但是,由于我有非常大的矩阵中的大量数据,即使在集群上重复此过程仍然需要很长时间,并且由于内存限制,组合矩阵不是一种选择。我想知道是否可以改用arrayfun 重写此代码,以便我可以利用它的 GPU 功能(因为 GPU 无法处理单元数组),但是自从辅助函数以来我遇到了问题

function avg = blockavg(mat,i,j,k)
i1 = (i-1)*k+1;
i2 = i*k;
j1 = (j-1)*k+1;
j2 = j*k
avg = mean(mean(mat(i1:i2,j1:j2)));
end

调用两个广播变量mat,一个nxn 矩阵,和k,一个标量,当插入arrayfun 时,这些不是数组输入。运行时

ii = 1:(n/k);
jj = 1:(n/k);
matavg = arrayfun(@blockavg,mat,ii,jj,k)

返回一条错误消息,指出输入参数必须是大小和形状相同的数组,因为只有 iijj 是数组输入,而 matk 不会因元素而异。我不太确定如何解决这个问题,或者即使arrayfun 完全可以进行这种类型的操作。任何建议表示赞赏。

谢谢!

【问题讨论】:

要解决您的输入大小问题,这可能会导致较慢的解决方案,您必须使用常量的标准模式。定义一个包含这些常量的匿名函数:matavg = arrayfun(@(ii,jj)(blockavg(mat,ii,jj,k)),mat,ii,jj,k)。但我认为这个解决方案比我建议的两个版本要慢。 【参考方案1】:

不使用图像处理工具箱的另一个不错的可能性:

squeeze(mean(mean(reshape(X,k,n/k,k,n/k),1),3))

这段代码以某种方式重塑了矩阵,每个块都可以通过 Y(a,:,b,:) 访问,这意味着它们具有相同的第一维和第三维索引。然后将均值应用于第一维和第三维,最后去除单维得到二维结果。

【讨论】:

谢谢!这将我的运行时间减少了大约一半。也感谢其他人的指点,非常感谢!【参考方案2】:

您正在尝试做的正是图像处理工具箱中的blockproc 所提供的:

blockproc(X,[k k],@(x)(mean(mean(x.data))))

为了加快速度,您可以尝试设置UseParallel-参数。

【讨论】:

以上是关于具有不同维度输入的函数的arrayfun的主要内容,如果未能解决你的问题,请参考以下文章

用于各种维度输入的高效 PyTorch DataLoader collat​​e_fn 函数

Matlab:arrayfun、cellfun、spfun 和 structfun 与简单的 for 循环

tensorflow常用函数解析

从函数返回指向数组的指针,函数名称后具有数组维度

pytorch输出与target维度不同

如何在 Matlab Coder 中为具有不同输入数量的函数定义输入类型?