下面的代码在给定协方差矩阵的情况下计算相关矩阵。我怎么能写得更好?问题是这部分代码将在尺寸大约为100 x 100的矩阵上运行1000次。
// Copy upper triangle of covariance matrix to correlation matrix
for(i = 0; i < rows; i++){
for(j = i; j < rows; j++){
corrmatrix.array[i * rows + j] = covmatrix.array[i * rows + j];
}
}
// Calculate upper triangle of corr matrix
for(i = 0; i < rows; i++){
root = sqrt(covmatrix.array[(i * rows) + i]);
for(j = 0; j <= i; j++){ // Move down
corrmatrix.array[ j * rows + i ] /= root;
}
k = i * rows;
for(j = i; j < rows; j++){ // Move across
corrmatrix.array[ k + j ] /= root;
}
}
// Copy upper triangle to lower triangle
for(i = 0; i < rows; i++){
k = i * rows;
for(j = i; j < rows; j++){
corrmatrix.array[ (j * rows) + i ] = corrmatrix.array[ k + j ];
}
}
我已经检查过行和列是否相等等,所以我只是在各处使用行。我想优化速度(显着)。
PS:
谢谢
答案 0 :(得分:1)
对我跳出的第一件事就是你在内循环中用相同的数字进行除法。
不要这样做。分工很慢。
你应该做的是乘以root
的倒数而不是重复除以:
inv_root = 1. / sqrt(covmatrix.array[(i * rows) + i]);
for(j = 0; j <= i; j++){ // Move down
corrmatrix.array[ j * rows + i ] *= inv_root;
}
k = i * rows;
for(j = i; j < rows; j++){ // Move across
corrmatrix.array[ k + j ] *= inv_root;
}
虽然这种优化对编译器来说似乎很明显,但由于浮点严格性,可能不允许进行此优化。您可以尝试使用-ffast-math
(在GCC中)或类似的东西来放宽浮点设置。