Matlab: Arrayfun with matrices

I am trying to rewrite the following code using arrayfun

A = ones(3,3,3)
for i = 1:3
    B(i) = trace(A(:,:,i));
end

I hope I tried

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

But it is simply (as one would expect) traced over each A(i,j,k)not A(:,:,i), as I would like. Then I tried to declare A{i}=ones(3,3)as a cell and go to arrayfun, but that didn't work either.

How can I vectorize functions on matrices in Matlab?

+4
source share
2 answers

bsxfuna vector-based solution that ab (uses) as tracedefined by - sum of diagonal elements-

%// 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)

If you want to preserve workspace attenuation with optional additional variables, avoid idxusing

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

GPUs, gpuArrays gpuArray(A), A GPU, gpuArray, gather(..).

, :

[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- .

+5

arrayfun, , :

arrayfun(@(i)trace(A(:,:,i)), 1:size(A,3))

, arrayfun !!, , - .

, , cellfun. .. A{i} = ones(3,3),

cellfun(@(x)trace(x), A)
+5

All Articles