MATLAB无循环实现三维矩阵B生成:由A构造n×n×m矩阵
嘿,这个需求我太熟悉了!要把那段循环代码改成无循环的高效实现,其实MATLAB里有几种非常简洁且性能拉满的方法,完全不用依赖arrayfun或者rowfun(这俩反而可能不如直接用广播高效)。下面给你详细拆解:
核心思路
首先得明确:你要生成的B(:,:,i)其实是向量A(:,i)的外积,也就是B(k,l,i) = A(k,i) * A(l,i)。本质上就是把A的每个元素和其他位置的元素做对应相乘,然后按页组织——这刚好是**广播(Broadcasting)**的拿手好戏!
方法1:隐式广播(推荐,MATLAB R2016b+)
从R2016b开始,MATLAB支持自动广播,不用再写bsxfun,代码超级简洁:
A = rand(n,m); % 把A分别变形为n×1×m和1×n×m,自动广播相乘得到n×n×m的B B = reshape(A, n, 1, m) .* reshape(A, 1, n, m);
或者更直观的写法(效果完全一样):
B = A(:,ones(1,n),:) .* A(ones(1,n),:,:);
这里A(:,ones(1,n),:)是把A的每一列重复n次,变成n×n×m的张量;A(ones(1,n),:,:)是把A的每一行重复n次,同样变成n×n×m的张量,然后对应元素相乘就得到了每个外积页。
方法2:bsxfun(兼容旧版本MATLAB)
如果你的MATLAB版本比较老(R2016b之前),就用bsxfun来实现广播逻辑:
A = rand(n,m); B = bsxfun(@times, reshape(A, n, 1, m), reshape(A, 1, n, m));
bsxfun(@times, X, Y)会自动扩展X和Y的维度,让它们可以做元素级乘法,和上面的隐式广播效果完全一致。
为什么这些方法比循环高效?
MATLAB的内置广播操作是用底层优化过的C代码实现的,完全避开了MATLAB解释器处理循环的开销。尤其是当n和m比较大的时候(比如n=100,m=1000),这些方法的速度会比循环快几倍甚至几十倍。
注意事项
如果n和m都很大,要留意内存占用:B是n×n×m的矩阵,比如n=1000、m=1000的话,B会占用约8GB内存(双精度),这时候得确保你的机器有足够的内存空间。
内容的提问来源于stack exchange,提问作者Mykola Servetnyk

