如何不使用for循环实现3D矩阵sub2ind的等效功能?
无循环实现原代码功能的高效方式
原代码的核心是遍历indX和indY的所有切片组合(共2×2=4组),将每组对应的索引对转换为线性索引后提取A的子矩阵并显示。以下是无需循环的实现方式:
A = rand(10,10); indX(:,:,1) = [2,3;1,6]; indX(:,:,2) = [2,5;2,6]; indY(:,:,1) = [4,6;2,3]; indY(:,:,2) = [7,5;3,4]; % 生成所有i和j的组合,得到4组索引对 [iComb, jComb] = meshgrid(1:2, 1:2); iComb = iComb(:); jComb = jComb(:); % 批量计算每组的线性索引,结果存为cell数组 ind = arrayfun(@(k) sub2ind(size(A), indX(:,:,iComb(k)), indY(:,:,jComb(k))), 1:4, 'UniformOutput', false); % 批量创建窗口并显示图像 cellfun(@(idx) figure(), ind); cellfun(@(idx) imagesc(A(idx)), ind);
关键说明:
- 索引组合生成:用
meshgrid快速生成i和j的所有配对,再转为列向量,一次性得到所有需要处理的切片组合。 - 批量索引计算:借助
arrayfun遍历每组组合,调用sub2ind生成对应线性索引,用cell数组存储不同组的索引矩阵(因为每组索引是2×2维度,无法统一为数值数组)。 - 批量图像显示:用
cellfun批量执行窗口创建和图像绘制操作,效果和原双重循环完全一致。
如果追求更简洁的写法,可将索引计算与显示合并:
[iComb, jComb] = meshgrid(1:2,1:2); arrayfun(@(i,j) imagesc(A(sub2ind(size(A),indX(:,:,i),indY(:,:,j)))), iComb(:), jComb(:));
效率与扩展性:
- 避免了显式双重循环,代码结构更紧凑;
- 对于小规模数据(如这里的4组),
arrayfun底层优化后的执行效率与循环相当; - 后续若增加
indX/indY的切片数量,仅需修改meshgrid的范围,无需调整核心逻辑。
内容的提问来源于stack exchange,提问作者MementoMori
相关产品推荐
相关产品推荐

