Matlab: 使用矩阵进行Arrayfun

4
我正在尝试使用arrayfun重写以下代码。
A = ones(3,3,3)
for i = 1:3
    B(i) = trace(A(:,:,i));
end

I hopefully tried

f = @(x) trace(x)
B = arrayfun(f, A);

但这只是(正如你所期望的)追踪每个单独的A(i,j,k),而不是我想要的A(:,:,i)。然后我尝试将A{i}=ones(3,3)声明为一个单元格,并传递给arrayfun,但这也没有起作用。
在Matlab中,我如何对矩阵进行函数向量化?

你好,想知道这里提供的任何一种解决方案是否适用于您? - Divakar
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - rwolst
2个回答

5
如果您真的想使用arrayfun,可以尝试这样的技巧:
arrayfun(@(i)trace(A(:,:,i)), 1:size(A,3))

请注意,arrayfun 不是矢量化操作,它只是循环的一个包装器,由于附加开销通常比循环更慢。
虽然同样不是矢量化操作,如果你要使用第二种方式,你应该只需要改为使用cellfun。例如,A{i}=ones(3,3)
cellfun(@(x)trace(x), A)

1
我想使用arrayfun,因为我正在GPU上运行代码。 我的想法是,使用arrayfun包装器可以加速我的计算,这种想法正确吗? - rwolst
@rwolst,我认为pagefun是GPU的等效于arrayfun。但请通过查看官方文档来确保这一点。 - Divakar
2
@Divakar:不,arrayfun是将循环推入GPU的好方法。当然,关于并行化开销的常规警告仍然适用。 - Jonas
1
@Divakar:抱歉,“好”的用词可能不是最恰当的。我是指“一种使事物在GPU上实际运行的方式”。Pagefun很可能更加优化,因此仅限于某些特定函数。 - Jonas
2
@Dan:你需要将数组定义为 gpuArrays,这需要使用并行计算工具箱。 - Jonas
显示剩余2条评论

5

基于bsxfun的向量化解决方案,利用了trace被定义为对角线元素之和的特点。

%// Get size of A
[m,n,r] = size(A) 

%// Get indices of the diagonal elements for each 3D "slice" as columns of idx
idx = bsxfun(@plus,[1:m+1:m*n]',[0:r-1]*m*n) %//'

%// Thus, for your 3 x 3 x 3 case, idx would be -
%//idx =
%//      1    10    19
%//      5    14    23
%//      9    18    27
%// and these are the linear indices to the diagonal elements to each `3D` slide.

%//Index into A with idx and sum along columns to get each element of desired output
B = sum(A(idx),1)

如果您想节省工作空间并避免不必要的额外变量,请避免使用带有“-”的idx

B = sum(A(bsxfun(@plus,[1:m+1:m*n]',[0:r-1]*m*n)),1)

处理GPU

如果需要处理 GPU,可以使用 gpuArray(A) 将其声明为 gpuArrays,然后对涉及 A 的后续操作将在 GPU 上执行,并且您将获得输出作为 gpuArray,您可以使用 gather(..) 将其作为 CPU 变量获取回来。

因此,完整的代码如下 -

[m,n,r] = size(A); %// Get size
gpu_A = gpuArray(A); %// copy data from CPU to GPU

%// Perform calculations on GPU
gpu_B = sum(gpu_A(bsxfun(@plus,[1:m+1:m*n]',[0:r-1]*m*n)),1); %//'

B = gather(gpu_B); %// get back output onto CPU

快速测试:使用我可以访问的GTX 750 Ti,这似乎比您的循环代码提供了3倍的加速。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接