【发布时间】: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)
返回一条错误消息,指出输入参数必须是大小和形状相同的数组,因为只有 ii 和 jj 是数组输入,而 mat 和 k 不会因元素而异。我不太确定如何解决这个问题,或者即使arrayfun 完全可以进行这种类型的操作。任何建议表示赞赏。
谢谢!
【问题讨论】:
-
要解决您的输入大小问题,这可能会导致较慢的解决方案,您必须使用常量的标准模式。定义一个包含这些常量的匿名函数:
matavg = arrayfun(@(ii,jj)(blockavg(mat,ii,jj,k)),mat,ii,jj,k)。但我认为这个解决方案比我建议的两个版本要慢。
标签: arrays matlab cuda gpu large-data