我想通过一个接受数组的函数传递3d矩阵的所有行(在特定维度上)。我知道我可以通过两个for循环来做到这一点,但这不是主意。
我尝试使用arrayfun,但无法正常工作。
linemean=@(x) mean(x) %it's just an example of fucntion
m=rand(3,3,3)
这样一来,我将在最后得到一个3x3矩阵,其元素对应于应用于每条m(i,j,:)行的linemean。任何帮助都会很棒。谢谢。
答案 0 :(得分:1)
专门用于mean
函数:
A = rand(3,3,3);
result = mean(A,3);
对于任意功能:
A = rand(3,3,3);
func = @(x) mean(x);
C = mat2cell(A,ones(1,size(A,1)),ones(1,size(A,2)),size(A,3));
result = cellfun(func,C);
注1: mat2cell
将矩阵分解为单独的较小矩阵,将它们存储在单元阵列中。我在上面所说的那样,它沿第1维和第2维剖析矩阵,从而创建了一个(3x3)单元阵列,每个单元中都包含一个(1x1x3)矩阵阵列。
注2: mean
在第一个非单维度上计算平均值,因此在第三个维度上具有维度(1x1x3)的每个像元中。如果您的任意函数的工作方式不同,例如严格沿一维求和,您可以将任意函数更改为func = @(x) arbitrFunc(squeeze(x))
之类的东西。 squeeze
将删除将每个单元格变成(3x1)矩阵的单例尺寸。
答案 1 :(得分:0)
如果只想对计算进行向量化,可以按以下步骤进行操作:
通过m
将3
重塑为size(m,1)*size(m,2)
(每列都是3维度的“线”)。
在每个列上执行计算,然后重塑为2D矩阵:
M = reshape(permute(m, [3, 1, 2]), [size(m,3), size(m,1)*size(m,2), 1]);
m_means = reshape(mean(M, 1), [size(m,1), size(m,2)]);
如果您必须使用arrayfun
,我有一个解决方案,但这有点尴尬:
解决方案假定m
是一个常数(不是arrayfun
的参数)。
% %Prepare 3x4x3 natrix for testing
m = cat(3, [1 2 3 4; 5, 6, 7, 8; 9, 10, 11, 12], [21 22 23 24; 25, 26, 27, 28; 29, 30, 31, 32], [41 42 43 44; 45, 46, 47, 48; 49, 40, 41, 42]);
%For testing:
%linemean=@(x) disp(num2str(m(floor(x/size(m,2))+1, mod(x, size(m,1))+1, :)));
%Use floor and mod for computing indices (ind2sub did't work)
linemean = @(x) mean(m(mod(x, size(m,1))+1, floor(x/size(m,1))+1, :));
%Apply arrayfun on array of indices 0:11
m_means = arrayfun(linemean, 0:size(m,1)*size(m,2)-1);
%Reshape to size of m
m_means = reshape(m_means, size(m,1), size(m,2))
结果:
m_means =
21.0000 22.0000 23.0000 24.0000
25.0000 26.0000 27.0000 28.0000
29.0000 26.6667 27.6667 28.6667