这个主题可能已经过时了,但是我解决了非常相似的问题,这个主题可能对其他人有用。
4 维非常小,因此直接计算矩阵求逆的算法是有效的。但是,如果您只需要一个解决方案的 A 矩阵,则无需计算整个反演。可以看出除以行列式(矩阵求逆中的一种运算)对于逆矩阵的所有项都不是必需的。您只能划分解的 4 个项,而不是所有 16 个矩阵项。还有一些其他的优化。这是我的 4D-solver 实现(c++ 代码)
void getsub(double* sub, double* mat, double* vec)
{
*(sub++) = *(mat ) * *(mat+5) - *(mat+1) * *(mat+4);
*(sub++) = *(mat ) * *(mat+6) - *(mat+2) * *(mat+4);
*(sub++) = *(mat ) * *(mat+7) - *(mat+3) * *(mat+4);
*(sub++) = *(mat ) * *(vec+1) - *(vec ) * *(mat+4);
*(sub++) = *(mat+1) * *(mat+6) - *(mat+2) * *(mat+5);
*(sub++) = *(mat+1) * *(mat+7) - *(mat+3) * *(mat+5);
*(sub++) = *(mat+1) * *(vec+1) - *(vec ) * *(mat+5);
*(sub++) = *(mat+2) * *(mat+7) - *(mat+3) * *(mat+6);
*(sub++) = *(mat+2) * *(vec+1) - *(vec ) * *(mat+6);
*(sub ) = *(mat+3) * *(vec+1) - *(vec ) * *(mat+7);
}
void solver_4D(double* mat, double* vec)
{
double a[10], b[10]; // values of 20 specific 2D subdeterminants
getsub(&a[0], mat, vec);
getsub(&b[0], mat+8, vec+2);
*(vec++) = a[5]*b[8] + a[8]*b[5] - a[6]*b[7] - a[7]*b[6] - a[4]*b[9] - a[9]*b[4];
*(vec++) = a[1]*b[9] + a[9]*b[1] + a[3]*b[7] + a[7]*b[3] - a[2]*b[8] - a[8]*b[2];
*(vec++) = a[2]*b[6] + a[6]*b[2] - a[0]*b[9] - a[9]*b[0] - a[3]*b[5] - a[5]*b[3];
*(vec ) = a[0]*b[8] + a[8]*b[0] + a[3]*b[4] + a[4]*b[3] - a[6]*b[1] - a[1]*b[6];
register double idet = 1./(a[0]*b[7] + a[7]*b[0] + a[2]*b[4] + a[4]*b[2] - a[5]*b[1] - a[1]*b[5]);
*(vec--) *= idet;
*(vec--) *= idet;
*(vec--) *= idet;
*(vec ) *= idet;
}
*mat表示指向A矩阵的指针
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
和*vec 以0 1 2 3 的形式表示惯性矢量。方法丢弃惯性向量并用新的替换它们。
您只需要 74 次乘法和 1 次除法。如果您在 SSE 优化方面经验丰富,此方法可能适用于 SSE 编码器(大多数操作是双重的)。
一般来说,这对所有可逆 A 矩阵都很有效。您可以将身份 a[7] = b[0] 用于对称 A 矩阵。不多,但是一般4维可逆A矩阵的原码还是挺快的。