该主题可能已过时,但是我解决了非常相似的问题,并且该主题可能对其他人有用。
4维非常小,因此直接计算矩阵求逆的算法是有效的。但是,如果您只需要一个解决方案的 A 矩阵,则无需计算整个反演。可以看出除以行列式(矩阵求逆中的一种运算)对于逆矩阵的所有项都不是必需的。您只能划分解的 4 个项,而不是所有 16 个矩阵项。还有一些其他的优化。这是我的 4D 求解器的实现(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矩阵的原码还是挺快的。