You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动