【发布时间】:2020-06-11 11:30:13
【问题描述】:
我创建了一个能够在 C++ 中计算矩阵行列式的小程序。我使用了 laplace-expansion,虽然我知道有更有效的方法来做到这一点:
double getDeterminantLaplace(const std::vector<std::vector<double>> vect) {
int dimension = vect.size();
if(dimension == 0) {
return 1;
}
if(dimension == 1) {
return vect[0][0];
}
//Formula for 2x2-matrix
if(dimension == 2) {
return vect[0][0] * vect[1][1] - vect[0][1] * vect[1][0];
}
double result = 0;
int sign = 1;
for(int i = 0; i < dimension; i++) {
//Submatrix
std::vector<std::vector<double>> subVect(dimension - 1, std::vector<double> (dimension - 1));
for(int m = 1; m < dimension; m++) {
int z = 0;
for(int n = 0; n < dimension; n++) {
if(n != i) {
subVect[m-1][z] = vect[m][n];
z++;
}
}
}
//recursive call
result = result + sign * vect[0][i] * getDeterminantLaplace(subVect);
sign = -sign;
}
return result;
}
我现在的问题是:如何让这个算法更高效?
我的一个想法是不创建“子矩阵”而只使用原始矩阵,但我真的不知道该怎么做。你怎么看这个想法?如何在 C++ 中做到这一点?
你还有什么想法吗?
【问题讨论】:
-
你可以通过引用传递
vect。 -
如果您有多个内核,您可以使用例如 openmp 来并行化外部以与 i 进行迭代。唯一的事情,对于 i = 0 到 i = 维度的变化是 i 本身和我可以看到的符号,如果我没记错我的数学课程,你可以通过 i 确定符号值,但对此我不太确定; )
-
如果你想尽可能高效地得到结果,而且这不是作业,我强烈建议你使用优化的库来做代数,例如Eigen。如果不花大量时间在这方面,你根本不可能在性能上接近它。