MATLAB中批量计算三维数组内3×3矩阵逆矩阵的高效方法咨询
高效实现高维度数组中每个3×3矩阵的求逆(MATLAB)
当然可以!完全不需要用三重循环来逐个求逆——MATLAB提供了专门的向量化工具和内置函数,能帮你高效处理这种高维度数组的页式矩阵运算,速度和代码简洁性都能碾压循环写法。
最推荐的方法:使用pageinv函数(MATLAB R2020b+)
如果你使用的是MATLAB R2020b或更新的版本,pageinv就是专门为你的场景设计的:它会自动遍历数组中每个"页"(也就是每个(i,j,k)对应的3×3矩阵),并计算其逆矩阵,全程无需手动循环,而且底层是优化过的线性代数库,效率极高。
用法超简单:
CoB_inv = pageinv(CoB);
一行代码直接得到和你三重循环完全一样的结果,但速度快N倍。
兼容旧版本的替代方案:arrayfun或向量化计算
如果你的MATLAB版本比较旧,没有pageinv,可以用以下两种方式:
方式1:arrayfun批量处理
arrayfun可以对数组的每个元素(这里就是每个3×3矩阵)应用inv函数,再把结果拼接回原维度的数组:
% 对每个(i,j,k)位置的3×3矩阵求逆,返回cell数组 CoB_inv_cell = arrayfun(@inv, CoB, 'UniformOutput', false); % 将cell数组转换回512×512×512×3×3的数值数组 CoB_inv = reshape(cell2mat(CoB_inv_cell), size(CoB));
这种写法比三重循环简洁,效率也更高,不过还是略逊于pageinv。
方式2:手动向量化计算逆矩阵(利用行列式+伴随矩阵)
对于3×3矩阵,我们可以利用线性代数公式,手动实现全向量化的逆运算(无需循环)。虽然代码稍长,但完全基于向量化操作,效率也不错:
% 计算每个3×3矩阵的行列式 det_CoB = det(CoB); % 计算每个位置的余子式(向量化提取子矩阵并求行列式) cof11 = det(CoB(:,:,:,2:3,2:3)); cof12 = -det(CoB(:,:,:,2:3,[1,3])); cof13 = det(CoB(:,:,:,2:3,1:2)); cof21 = -det(CoB(:,:,:,[1,3],2:3)); cof22 = det(CoB(:,:,:,[1,3],[1,3])); cof23 = -det(CoB(:,:,:,[1,3],1:2)); cof31 = det(CoB(:,:,:,1:2,2:3)); cof32 = -det(CoB(:,:,:,1:2,[1,3])); cof33 = det(CoB(:,:,:,1:2,1:2)); % 构造伴随矩阵(余子式矩阵的转置) adj_CoB = cat(4, ... cat(5, cof11, cof21, cof31), ... cat(5, cof12, cof22, cof32), ... cat(5, cof13, cof23, cof33)); % 逆矩阵 = 伴随矩阵 / 行列式 CoB_inv = adj_CoB ./ det_CoB;
额外优化:后续矩阵运算也用页式函数
你提到后续要做M = S*D*S^(-1)的运算,这里同样可以用pagemtimes函数来实现页式矩阵乘法,全程无循环:
% 假设D是和CoB同维度的对角矩阵数组 M = pagemtimes(pagemtimes(CoB, D), CoB_inv);
补充:如果CoB是正交矩阵
如果你的基变换矩阵CoB是正交矩阵(特征向量正交归一化),那它的逆矩阵就是转置矩阵,这时候直接交换最后两个维度就能得到,速度最快:
CoB_inv = permute(CoB, [1,2,3,5,4]);
不过这个前提是CoB必须是正交矩阵,否则结果不对,所以只有确认满足条件时再用。
内容的提问来源于stack exchange,提问作者Shakthi Visagan




