对于 3 x 3 矩阵的求逆,一个人能否胜过 Cramer 规则?

计算科学 线性代数 算法
2021-12-19 14:06:20

我知道对于一般矩阵,Cramer 规则对于矩阵逆的数值计算来说远非理想。但是,它是否可以在以下情况下超越3×3矩阵?一个特别的优点是该算法是非分支的。例如,逆的转置可以如下实现,假设矩阵是可逆的并且矩阵存储为连续数组。aab

void inverse3(double* a, double* b) {
    // cofactors
    b[0] = a[4]*a[8] - a[5]*a[7];
    b[1] = a[5]*a[6] - a[3]*a[8];
    b[2] = a[3]*a[7] - a[4]*a[6];
    b[3] = a[7]*a[2] - a[8]*a[1];
    b[4] = a[8]*a[0] - a[6]*a[2];
    b[5] = a[6]*a[1] - a[7]*a[0];
    b[6] = a[1]*a[5] - a[2]*a[4];
    b[7] = a[2]*a[3] - a[0]*a[5];
    b[8] = a[0]*a[4] - a[1]*a[3];
    // determinant
    double det = b[0]*a[0] + b[1]*a[1] + b[2]*a[2];
    // inverse
    b[0] /= det;
    b[1] /= det;
    b[2] /= det;
    b[3] /= det;
    b[4] /= det;
    b[5] /= det;
    b[6] /= det;
    b[7] /= det;
    b[8] /= det;
}

这可以在效率或数值稳健性方面得到改善吗?

2个回答

我不知道另一个因式分解总体上是否会更快,但是您(几乎)可以通过将行列式反转一次并乘以倒数 9 而不是一遍又一遍地执行除法来加快上述代码的速度。编译器可能会为您解决这个问题,但不能保证(查看程序集)。

编辑添加:为了记录,英特尔 13 编译器的几次尝试会根据它对除数的了解给出不同的结果。如果它来自命令行输入,那么编译器会尽职尽责地划分每一个(在我的 Sandy Bridge 机器上矢量化)。

就数值稳健性而言,是的,当然。例如,det可能会在您的代码中溢出;基于 Givens QR 分解的方法不会代替。我还猜想在你的辅因子计算中可能会有显着的取消。

恐怕你不能同时拥有完美的稳定性和最少的操作;您必须选择您希望改进的两个方向中的哪一个。