我试图创建一个矩阵,其中包含较大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
和{{1}不要因元素而异。我不太确定如何解决此问题,或者即使k
完全可以执行此类操作。任何建议都表示赞赏。
谢谢!
答案 0 :(得分:2)
不使用图像处理工具箱的另一个好处:
squeeze(mean(mean(reshape(X,k,n/k,k,n/k),1),3))
此代码以某种方式重新整形矩阵,每个块都可以通过Y(a,:,b,:)访问,这意味着它们具有相同的第一维和第三维索引。然后将mean应用于第一维和第三维,最后删除单个维度以得到2d结果。
答案 1 :(得分:1)
您要做的就是图像处理工具箱提供的blockproc
:
blockproc(X,[k k],@(x)(mean(mean(x.data))))
要加快速度,您可以尝试设置UseParallel
- 参数。